spring事务传播
• PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择,默认。
• PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
• PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
• PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
• PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
• PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
隔离级别(默认数据库的隔离级别)
- Serializable:最严格的级别,事务串行执行,资源消耗最大;
- REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
- READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
- Read Uncommitted:保证了读取过程中不会读取到非法数据。隔离级别在于处理多事务的并发问题。
基于JDK动态代理 <tx:annotation-driven transaction-manager="txManager"/> 只对公开接口的方法有效,即注解,xml配置接口的公开方法上。
基于CGLIB类代理 <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/> 只对具体类有效,即注解,xml配置具体类的的公开方法上。
基于aspectj的 <tx:annotation-driven transaction-manager="txManager" mode="aspectj" proxy-target-class="true"/> 类,接口都有效。
共享锁(S):共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
排他锁(X):排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
另外,为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁。
意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。
X | IX | S | IS | |
X | 冲突 | 冲突 | 冲突 | 冲突 |
IX | 冲突 | 兼容 | 冲突 | 兼容 |
S | 冲突 | 冲突 | 兼容 | 兼容 |
IS | 冲突 | 兼容 | 兼容 | 兼容 |
对于insert、update、delete,InnoDB会自动给涉及的数据加排他锁(X);对于一般的Select语句,InnoDB不会加任何锁,事务可以通过以下语句给显示加共享锁或排他锁。
共享锁:SELECT ... LOCK IN SHARE MODE;
在读取的行上设置一个共享模式的锁。这个共享锁允许其它session读取数据但不允许修改它。 行读取的是最新的数据,如果他被其它事务使用中而没有提交,读取锁将被阻塞知道那个事务结束。
排他锁:SELECT ... FOR UPDATE;
在读取行上设置一个排他锁。组织其他session读取或者写入行数据