答案:
即ACID:
答案: 支持的事务管理类型有两种
Spring支持两种类型的事务管理:
@Autowired
TransactionTemplate transactionTemplate ;
@Transactional
:答案: 实现声明式事务的三种方式
和
的xml声明式事务管理:和Spring AOP结合,利用切点表达式使得事务管理更加灵活答案:
两个事务方法之间的嵌套调用时
,这个事务方法如何进行,即事务的传播特性。
@Transactional
public void trans(){
sub();
log();
query();
}
@Transactional //SUPPORTS
public info query(){
}
@Transactional //REQUIRES_NEW
public void log(){
}
以上面的query方法为例,其用SUPPORTS,即单独执行时不开启事务(就一个查询,当然不用开启),被有事务的外部方法调用时,则融入到这个外部方法的事务中,与他们同成功,同失败。(到大学了,和其余室友住一个屋子,还是你自己外面租一个新房子)
答案:
事务隔离用来解决并发事务所产生的一些问题:
通过设置不同的隔离级别,可解决以上问题。
脏读:
事务2只是改了余额,但并未提交,事务1就把这个没提交的值读走了,如果以后事务2最终回滚,就出问题了。即一个事务读取了另一个事务中没有提交的数据,会在本事务中产生数据不一致的问题。
@Transactional(isolation = isolation.READ_COMMITTED)
设置事务隔离策略为读已提交,只读别的并发事务已提交的修改
。
不可重复读:
事务1先读后去处理其他事儿,然后期间事务2修改并commit,等事务1再读,则产生数据不一致的问题。
@Transactional(isolation = isolation.REPEATABLE_READ)
设置事务隔离策略为可重复读REPEATABLE_READ,确保事务1可以多次从一个字段中读到相同的值,即事务1执行期间禁止其他事务对这个字段进行更新(行锁)
。
幻影读:
不可重复读是针对一行数据,而幻影读则是针对整个表
,比如两次读取,表中多出了一行数据:
即一个事务所在的方法中,多次进行整表数据读取,结果不一样,产生数据不一致问题。
@Transactional(isolation = isolation.SERIALIZABLE)
需要设置事务级别为串行化SERIALIZABLE
,确保事务1可以多次从一个表中读到相同的行数,事务1执行期间,禁止其他事务对这个表进行增删改,但这样性能十分低下(表锁)
最后,当不设置事务隔离级别时,将默认使用底层所选数据库自身的默认事务隔离级别。
SELECT @@tx_isolation;
以JavaConfig的方式为例,使用是:
//启动事务,这样可以使用@Transactional注解
@EnableTransactionManagement
答案:
没有Spring之前,单靠JDBC来操作是这样的:
try {
//...
//将事务提交机制改为手动提交
conn.setAutoCommit(false);
//业务逻辑
//在这里事务结束,手动提交数据
conn.commit();
}
Spring事务是把上面业务逻辑前后的事务开启与提交用AOP包了一下,即原理是:Spring事务底层是基于数据库事务和AOP机制。
try{
- 创建数据库连接
- 修改数据库连接的autocommit属性为false,禁止此连接自动提交
- 执行当前方法,方法中会执行数据库操作的业务SQL
-
}catch{
- 若出现异常,且这个异常需要回滚,则回滚事务
}
答案:
Spring的事务信息是存于ThreadLocal中的,所以一个线程永远只能有一个事务。对于被调用的事务方法,当:
详细流程:
TransactionInfo.newTransaction=true
)内部调用了另一个事务方法
情况一,当传播行为是融入
:
TransactionInfo.newTransaction=false
),即不是一个新事务情况二,当传播行为是创建新的事务
:
TransactionInfo.newTransaction=true
),即新事务,并放入ThreadLocal当中
问题分析:两个事务方法A和B,在两个线程中,对应的事务能否同时提交或回滚?
答案:
Spring不支持,因为Spring事务信息存于ThreadLocal中的Connection,一个线程永远只能有一个事务,所以无法实现两个事务的一致性。可以通过编程式事务自己控制或者分布式事务来解决(二阶段提交的方式)。
Spring事务底层是基于数据库事务和AOP机制,因此,参考AOP失效,可以知道Spring事务失效的原因:
答案:
后面几种本质上是使用不当导致的失效。