1. 事务的4种特性
序号
|
参数
|
含义
|
1
|
原子性(Atomicity)
|
事务是数据库的逻辑工作单位,它对数据库的修改要么全部执行,要么全部不执行。
|
2
|
一致性(Consistemcy)
|
事务前后,数据库的状态都满足所有的完整性约束。
|
3
|
隔离性(Isolation)
|
并发执行的事务是隔离的,一个不影响一个。通过设置数据库的隔离级别,可以达到不同的隔离效果
|
4
|
持久性(Durability)
|
在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
|
2.Transactional()控制事务传播的配置项目(默认Propagation.REQUIRED)
@Transactional(propagation=Propagation.REQUIRED) //控制事务传播。默认是Propagation.REQUIRED
@Transactional(isolation=Isolation.DEFAULT) //控制事务隔离级别。默认跟数据库的隔离级别相同
@Transactional(readOnly=false) //控制事务可读写、只可读。默认可读写
@Transactional(timeout=30) //控制事务的超时时间,单位秒。默认跟数据库的事务控制系统相同
@Transactional(rollbackFor=RuntimeException.class) //控制事务遇到哪些异常会回滚。默认是RuntimeException
@Transactional(rollbackForClassName=RuntimeException) //同上
@Transactional(noRollbackFor=NullPointerException.class) //控制事务遇到哪些异常不会回滚。默认遇到RuntimeException回滚
@Transactional(noRollbackForClassName=NullPointerException)//同上
3.事务的7中传播特性4. 事务的传播案例:
序号 | 传播行为 | 含义 |
1 | REQUIRED | 如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。 |
2 | SUPPORTS | 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行 |
3 | MANDATORY | 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。 |
4 | NESTED | 如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行 |
5 | NEVER | 总是非事务地执行,如果存在一个活动事务,则抛出异常 |
6 | REQUIRES_NEW | 总是开启一个新的事务。如果一个事务已经存在,则将这个已经存在的事务挂起 |
7 | NOT_SUPPORTED | 总是非事务地执行,并挂起任何存在的事务 |
4.举个上手的按例:事务在A类的a()方法中调用B类的b()方法的传播案例
A.a() | B.b()的事务配置 | a()没有事务的结果 | a()有事务的结果 |
REQUIRED | b()创建自己的事务; | b()接受a()的事务 |
SUPPORTS | b()不创建自己的事务; | b()接受a()的事务 |
MANDATORY | b()报异常 | b()接受a()的事务 |
NESTED | b()创建自己的事务; | b()接受a()的事务,成为a()嵌套的子事务 |
NEVER | b()不创建自己的事务; | b()报异常 |
REQUIRES_NEW | b()创建自己的事务; | b()不接受a()的事务,b()先执行,内层事务失败不会影响外层事务 |
NOT_SUPPORTED | b()不创建自己的事务; | b()不接受a()的事务,b()先执行 |
Java案例:
public class PropagationTest extends BaseServerTest {
private static final Logger logger = Logger.getLogger(PropagationTest.class);
@Test
@Transactional()
public void a() {
try {
PropagationTestB classb = new PropagationTestB();
classb.b();
} catch (Exception e) {
throw new RuntimeException();
class PropagationTestB {
@Autowired
TRSMapper trsMapper;
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false, rollbackFor = RuntimeException.class)
public void b() {
try {
trsMapper.saveNews(new JSONArray());
} catch (Exception e) {
throw new RuntimeException();
5.特殊案例分析:
Java案例:无事务a()方法中调用同一个类的有事务b()方法问题案例
public class PropagationTest extends BaseServerTest {
private static final Logger logger = Logger.getLogger(PropagationTest.class);
@Autowired
TRSMapper trsMapper;
@Test
public void a() {
try {
} catch (Exception e) {
throw new RuntimeException();
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false, rollbackFor = RuntimeException.class)
public void b() {
try {
trsMapper.saveNews(new JSONArray());
} catch (Exception e) {
throw new RuntimeException();
声明式事务基于Spring AOP实现,将具体业务逻辑与事务处理解耦,在 Spring 的 AOP 代理下,只有目标方法由外部调用,目标方法才由 Spring 生成的代理对象来管理,这会造成自调用问题。
同一类中a()方法没有@Transactional 注解,在其内部调用有@Transactional 注解的方法,有@Transactional 注解的方法b()的事务被忽略,不会发生回滚。
1. 事务的4种特性 序号 参数 含义 1 原子性(Atomicity) 事务是数据库的逻辑工作单位,它对数据库的修改要么全部执行,要么全部不执行。 2 一致性(Consistemcy) 事务前后,数据库的状态都满足所有的完整性约束。 3 隔离性(Isolation) 并发执行的事务是隔离的,一个不影响一个。通过设置数据...
Spring中 @Transactional 注解的限制
同一个类中, 一个nan-transactional的方法去调用transactional的方法, 事务会失效
If you use (default) Spring Proxy AOP, then all AOP functionality provided by Spring (like @Transational) will o...
事务方法调用非事务方法(相同类下)
import edu.haut.springboottest.entity.TestTable;
import edu.haut.springboottest.mapper.TestTableMapper;
import org.springframework.stereotype.Service;
import org.springframework
加粗样式我们都是知道,在同一个类,无事务方法调用有事务的方法,事务不会生效,对此作阐释的文章网上也很多,那反过来呢?
public class AdminService {
@Autowired
AdminDao adminDao;
@Transactional(rollbackFor = Exception.class)
public int updateAdmin(AdminPo adminPo) {
int result = adminDao.
介绍:我们日常开发中很常用的就是spring的事务管理,我们通常使用声明式事务
声明式事务:基于AOP面向切面的,它将具体业务与事务处理部分解耦,代码侵入性很低,所以在实际开发中声明式事务用的比较多。声明式事务也有两种实现方式,是基于TX和AOP的xml配置文件方式,二种就是基于@Transactional注解了,现在我们通常使用注解的方式
使用场景:@Transactional 可以作用在接口、类、类方法,我们通常使用在方法上
作用:当作用于方法上时,此 public 方法将具有该类型的事务属性..
转自:https://blog.csdn.net/weixin_36586564/article/details/105687331?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-1&spm=1001.2101.3001.4242
方法A调用方法B:
1、如果只有A加@Transactional注解;则AB在同一事务中,任意异常都回滚;
2、如果只有B加@Transactional注解;AB方法为同一类,事务失
方法A调用方法B:
如果A和B方法在同一个类中:
如果A加@Transactional注解,B加不加@Transactional注解,事务是有效的,则AB在同一事务中。
如果A不加@Transactional注解,B加不加@Transactional注解,事务都是无效的。
如果A和B不在同一个类中:
如果A加@Transactional注解,B加不加@Transactional注解,事务是有效的。
如果A不加@Transactional注解,B加了@Transactional注解,只有B是有事务的;
先声明这篇文章并非原创,是转载了一位大佬的文章,看完后,写的确实不错,对主要内容做了整理。文末有大佬的原创链接
项目环境:sprinigboot
项目场景:每天定时更新xx的数据,某条记录更新中数据出错,不影响整体数据,只需记录下来并回滚当条记录所关联的表数据。
在一个service里拆成了两个方法去执行,一个方法(A)是查询数据与验证组装数据,另外一个方法(B)更新这条数据所对应的表(执行的时候是方法A中调用方法B)。由于这个数据是循环更新,所有一条数据更新失败直接回滚此条数据,不影响其他数据,其他的照常
方法A调用方法B:
1、如果只有A加@Transactional注解;则AB在同一事务中;
2、如果只有B加@Transactional注解;AB方法为同一类,事务失效;AB不同类,只有B有事务;
spring 在扫描bean的时候会扫描方法上是否包含@Transactional注解,如果包含,spring会为这个bean动态地生成一个子类(即...
在Java中,@Transactional注解是Spring框架中用来控制事务的注解。当我们在一个类中调用事务方法时,如果这个类自身被注入到Spring容器中,那么@Transactional注解是可以正常工作的。但是,如果这个类是通过new关键字创建的对象,而不是通过Spring容器注入的对象,那么@Transactional注解就会失效。
这是因为@Transactional注解的实现原理是通过Spring AOP动态代理技术生成一个代理类来处理事务。当一个类被注入到Spring容器中时,Spring会对这个类进行增强,生成一个代理类,从而使@Transactional注解生效。但是如果我们通过new关键字创建一个对象,这个对象并没有被Spring容器管理,也就没有被增强,因此@Transactional注解就无法生效了。
举个例子,假设我们有一个UserService类,其中有一个addUser方法使用了@Transactional注解来控制事务:
```java
@Service
public class UserService {
@Autowired
private UserDao userDao;
@Transactional
public void addUser(User user) {
userDao.addUser(user);
如果我们在另一个类中创建一个UserService对象,并调用其addUser方法,那么@Transactional注解就会失效:
```java
public class OtherClass {
public void doSomething() {
UserService userService = new UserService(); // 创建UserService对象
User user = new User();
user.setName("test");
userService.addUser(user); // 调用addUser方法,@Transactional注解失效
因此,在使用@Transactional注解时,我们需要注意在哪些地方创建了对象,确保事务注解能够正常工作。
案例:解决SimpleDateFormat格式化时间异常 java.lang.NumberFormatException: For input string: "20022E.20022E44"
开发必备小知识