122
社区成员
发帖
与我相关
我的任务
分享@
Spring的声明式事务管理基于AOP(面向切面编程),通过代理机制在方法执行前后添加事务的开始和结束操作。Spring事务管理器(PlatformTransactionManager)负责创建和维护事务。
@Transactional注解可以应用于类或方法上,表示被注解的方法需要事务管理。以下是一些常用的属性:
什么是事务的传播行为?
在service类中有a()方法和b()方法,a()方法上有事务,b()方法上也有事务,当a()方法执行过程中调用了b()方法,事务是如何传递的?合并到一个事务里?还是开启一个新的事务?这就是事务传播行为。
事务传播行为在spring框架中被定义为枚举类型:
一共有七种传播行为:
@Transactional(propagation = Propagation.REQUIRED)
编写程序测试一下传播行为:
@Transactional(propagation = Propagation.REQUIRED)
public void save(Account act) {
accountDao.insert(act); // 保存act-001账户
// 创建账户对象
Account act2 = new Account("act-002", 1000.0);
try {
accountService.save(act2); // 保存act-002账户
} catch (Exception e) {
}
// 继续
}
@Override
//@Transactional(propagation = Propagation.REQUIRED)
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void save(Account act) {
accountDao.insert(act);
// 模拟异常
String s = null;
s.toString();
// 事儿没有处理完,这个大括号当中的后续也许还有其他的DML语句。
}
事务隔离级别类似于教室A和教室B之间的那道墙,隔离级别越高表示墙体越厚。隔音效果越好。
数据库中读取数据存在的三大问题:(三大读问题)
事务隔离级别包括四个级别:
在Spring代码中如何设置隔离级别?
隔离级别在spring中以枚举类型存在:

@Transactional(timeout = 10)
以上代码表示设置事务的超时时间为10秒。
表示超过10秒如果该事务中所有的DML语句还没有执行完毕的话,最终结果会选择回滚。
默认值-1,表示没有时间限制。
这里有个坑,事务的超时时间指的是哪段时间?
在当前事务当中,最后一条DML语句执行之前的时间。如果最后一条DML语句后面很有很多业务逻辑,这些业务代码执行的时间不被计入超时时间。
以下代码的超时不会被计入超时时间
@Transactional(timeout = 10) // 设置事务超时时间为10秒。
public void save(Account act) {
accountDao.insert(act);
// 睡眠一会
try {
Thread.sleep(1000 * 15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
以下代码超时时间会被计入超时时间
@Transactional(timeout = 10) // 设置事务超时时间为10秒。
public void save(Account act) {
// 睡眠一会
try {
Thread.sleep(1000 * 15);
} catch (InterruptedException e) {
e.printStackTrace();
}
accountDao.insert(act);
}
(如果想让整个方法的所有代码都计入超时时间的话,可以在方法最后一行添加一行无关紧要的DML语句。)
代码如下:
@Transactional(readOnly = true)
将当前事务设置为只读事务,在该事务执行过程中只允许select语句执行,delete insert update均不可执行。
该特性的作用是:启动spring的优化策略。提高select语句执行效率。
如果该事务中确实没有增删改操作,建议设置为只读事务。
Spring的声明式事务管理提供了一种简单而强大的事务处理机制,通过合理配置@Transactional注解的属性,可以确保事务的一致性和隔离性。在实际开发中,需要根据业务需求和系统特点,选择合适的事务传播行为和隔离级别,并注意调整事务超时时间和只读属性。