Atomicity:原子性,一个事务不可以被拆分
Consistency:一致性,
Isolation:隔离性,多个事务操作数据,不能相互影响
Durability:持久性,
在SQL92标准中,事务隔离级别分为四种,分别为:
隔离级别(低->高) | 脏读 | 不可重复读 | 幻读 | 第一类更新丢失 | 第二类更新丢失 | 数据库默认级别 | |
read uncommitted | 读取未提交的内容 | y | y | y | y | y | |
read committed | 读已提交 | x | y | y | x | y | oracle\sql server |
repeatable read |
可重复读 | x | x | y |
x | x | mysql |
serializable |
可串行化 | x | x | x | x | x |
其中Read Uncommitted与Read Committed为语句级别的, 而Read Repeatable与Serializable是针对事务级别的。
1.1.1 mysql-InnoDB引擎默认事务隔离级别repeatable-read
1.1.2 sqlServer,Oracle默认事务隔离级别read commited
1.1.2 查询与设置事务隔离级别
1.1.2.1 mysql
#mysql版本 select version(); #存储引擎的事务隔离级别 select @@global.tx_isolation,@@tx_isolation; #设置会话事务隔离级别 set session tx_isolation='serializable'; #设置全局的事务隔离级别 set global tx_isolation='serializable'; set session transaction isolation level read committed;
1.1.2.2 sql Server
1.2.1脏读:数据已修改事务没提交,另一事务读取到未提交的数据!(事务没提交另一事务就读到未提交的数据)
1.2.2不可重复读:同一事务两次读取数据不一样;第一个事务读去数据,第二个事务修改数据提交,第一个事务再一次读取数据,这样第一个事务两次读取的数据将不一致。
1.2.3幻读:两个事务,第一个事务将所有行的数据都修改了,第二个事务将插入一条数据提交,第1个事务提交发现有一条数据并没有修改。
1.2.4第一类丢失(回滚丢失):
当2个事务更新相同的数据源,如果第一个事务被提交,而另外一个事务却被撤销,那么会连同第一个事务所做的跟新也被撤销。也就是说第一个事务做的跟新丢失了
1.2.5第二类更新丢失(覆盖丢失)
加深理解:
不可重复读和幻读的区别
两者都是相同事务两次读取不一致,一个是被另外事务修改读取不一致,一个是被另外事务插入读取不一致。
不可重复读,针对表内的修改,只需要锁住满足条件的记录,加锁的方式不同
幻读,针对表内的插入,要锁住满足条件及其相近的记录
2.1 数据库锁
2.1.a 引用文章
http://www.cnblogs.com/zhouqianhua/archive/2011/04/15/2017049.html
2.1.1读锁(共享锁):
2.1.2更新锁:
2.1.3写锁(排他锁):
2.1.4意向锁:
2.1.5计划锁:
2.2 数据库锁粒度
表锁:管理锁的开销最小,同时允许的并发量也最小的锁机制。MyIsam存储引擎使用的锁机制。当要写入数据时,把整个表都锁上,此时其他读、写动作一律等待。在MySql中,除了MyIsam存储引擎使用这种锁策略外,MySql本身也使用表锁来执行某些特定动作,比如alter table.
行锁:可以支持最大并发的锁策略。InnoDB和Falcon两张存储引擎都采用这种策略。
注意:
SELECT ... FOR UPDATE ,不过锁定(Lock)的数据是判别就得要注意一下了。由于InnoDB 预设是Row-Level Lock,所以只有查询条件要指定索引并预防索引失效,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table Lock (将整个数据表单给锁住)
LOCK TABLE和UNLOCK TABLE 表锁
引用文章:http://blog.csdn.net/it_man/article/details/5074371
事务在方法中传播。
PROPAGATION_REQUIRED
RROPAGATION_REQUIRES_NEW
PROPAGATION_NESTED
PROPAGATION_SUPPORTS
PROPAGATION_NOT_SUPPORTED
PROPAGATION_NEVER
PROPAGATION_MANDATORY
首先要明确的是,事务是从哪里来?传播到哪里去?答案是,从方法 A 传播到方法 B。Spring 解决的只是方法之间的事务传播,那情况就多了,比如:
方法 A 有事务,方法 B 也有事务。
方法 A 有事务,方法 B 没有事务。
方法 A 没有事务,方法 B 有事务。
方法 A 没有事务,方法 B 也没有事务。
假设事务从方法 A 传播到方法 B,您需要面对方法 B,问自己一个问题:
方法 A 有事务吗?
如果没有,就新建一个事务;如果有,就加入当前事务。这就是 PROPAGATION_REQUIRED,它也是 Spring 提供的默认事务传播行为,适合绝大多数情况。
如果没有,就新建一个事务;如果有,就将当前事务挂起。这就是 RROPAGATION_REQUIRES_NEW,意思就是创建了一个新事务,它和原来的事务没有任何关系了。
如果没有,就新建一个事务;如果有,就在当前事务中嵌套其他事务。这就是 PROPAGATION_NESTED,也就是传说中的“嵌套事务”了,所嵌套的子事务与主事务之间是有关联的(当主事务提交或回滚,子事务也会提交或回滚)。
如果没有,就以非事务方式执行;如果有,就使用当前事务。这就是 PROPAGATION_SUPPORTS,这种方式非常随意,没有就没有,有就有,有点无所谓的态度,反正我是支持你的。
如果没有,就以非事务方式执行;如果有,就将当前事务挂起。这就是 PROPAGATION_NOT_SUPPORTED,这种方式非常强硬,没有就没有,有我也不支持你,把你挂起来,不鸟你。
如果没有,就以非事务方式执行;如果有,就抛出异常。这就是 PROPAGATION_NEVER,这种方式更猛,没有就没有,有了反而报错,确实够牛的,它说:我从不支持事务!
如果没有,就抛出异常;如果有,就使用当前事务。这就是 PROPAGATION_MANDATORY,这种方式可以说是牛逼中的牛逼了,没有事务直接就报错,确实够狠的,它说:我必须要有事务!
声明式事务:TransactionProxyFactoryBean 在spring 配置文件中进行配置或者使用注解
编程式事务:TransactionTemplate PlatformTransactionManager
8 - Serializable 串行化
4 - Repeatable Read 可重复读
2 - Read Commited 可读已提交
1 - Read Uncommited 可读未提交
在hibernate.cfg.xml中使用hibernate.connection.isolation参数配置数据库事务隔离级别
悲观锁
乐观锁
http://www.cnblogs.com/otomedaybreak/archive/2012/01/27/2330008.html#C4
http://www.iteye.com/topic/332577
http://my.oschina.net/huangyong/blog/160012?p=4#comments