多个事务间发生冲突解决方法

多个事务间发生冲突解决方法

悲观锁:在sql语句后+for update

为保证数据的一致性和完整性,每次读写数据时都会先加锁,这样可以避免其他事务进行读写的并发操作

通常使用synchronized来实现

乐观锁:在where中判断版本号是否一致

提交数据更改时检查是否有其他事务修改这条数据,若没有,就提交更改,否则回滚事务(CAS)

认为不太可能出现冲突

CAS:无锁状态下,多个线程对一个值的更新

之前:上锁后其他线程不能访问,为提高效率,判断需要修改的值是否被其他线程修改更新过(ABA问题,向需要改变的值加一个版本号)

遇到的问题+例子

当有多个请求同时访问时,出现了多个线程同时访问的情况

解决方案:@Transactional注解

1、为方法添加事务

2、可指定隔离级别避免出现脏读、幻读、不可重复读

3、可指定传播机制

4、指定是否可读等

隔离级别
数据库的事务隔离 

    脏读: 表示一个事务能够读取另一个事务中还未提交的数据

    不可重复读:指的是在一个事务内,事务 A 多次读取同一数据,但事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。

    幻读: 比如说一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。

  1. ISOLATION_READ_UNCOMMITTED:‌这是事务最低的隔离级别,‌允许另一个事务可以看到这个事务未提交的数据。‌这种隔离级别会产生脏读、‌不可重复读和幻读。‌
  2. ISOLATION_READ_COMMITTED:‌保证一个事务修改的数据提交后才能被另一个事务读取。‌另一个事务不能读取该事务未提交的数据。‌
  3. ISOLATION_REPEATABLE_READ:‌这种事务隔离级别可以防止脏读、‌不可重复读。‌但是可能出现幻像读。‌它除了保证一个事务不能读取另一个事务未提交的数据外,‌还保证了避免下面的情况产生(‌不可重复读)‌。‌
  4. ISOLATION_SERIALIZABLE:‌这是花费最高代价但是最可靠的事务隔离级别。‌事务被处理为顺序执行。‌除了防止脏读、‌不可重复读外,‌还避免了幻读。‌(性能低)

默认情况下,‌@Transactional使用的隔离级别与具体的数据库相关。‌例如,‌MySQL的默认隔离级别是REPEATABLE READ,‌而Oracle的默认隔离级别是READ COMMITTED。‌

传播行为(Propagation)
  • REQUIRED:默认传播行为,当前方法在现有事务中执行,如无事务则创建新事务。
  • REQUIRES_NEW:当前方法必须在一个新的事务中执行,暂停现有事务。
  • MANDATORY:必须在现有事务中执行,如无事务则抛出异常。
  • SUPPORTS:当前方法支持事务,但无事务时非事务执行。
  • NOT_SUPPORTED:当前方法非事务方式执行,如有事务则挂起。
  • NEVER:当前方法必须在非事务中执行,如有事务则抛出异常。
  • NESTED:在现有事务中执行,如无事务则创建新事务,并允许嵌套提交和回滚。
回滚规则(Rollback Rules)

回滚规则定义了在何种情况下事务需要回滚。@Transactional注解默认对运行时异常(如 RuntimeException 和 Error)进行回滚,而不回滚受检异常(如 Exception)。

  • rollbackFor:指定哪些异常需要回滚。
  • noRollbackFor:指定哪些异常不需要回滚。

synchronized关键字

当两个并发线程(thread1和thread2)访问同一个对象中的代码块时,在同一时刻只能有一个线程得到执行,另一个线程受阻塞,必须等待当前线程执行完这个代码块以后才能执行该代码块。Thread1和thread2是互斥的,因为在执行synchronized代码块时会锁定当前的对象,只有执行完该代码块才能释放该对象锁,下一个线程才能执行并锁定该对象

使用方法:
1.synchronized(this){}包含需要加锁的代码块

2.synchronized加在public的方法上

缺点:线程排队等待,运行时间较长

最后,欢迎大家补充其他见解~

  • 22
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 定时器执行事务可能会发生多线程冲突,因为定时器是在一个单独的线程中执行的,而事务可能会在其他线程中执行。如果在定时器执行期修改了共享资源,可能会导致多线程冲突。因此,在编写定时器代码时,需要考虑多线程安全性。 ### 回答2: 定时器执行事务可能会发生多线程冲突。 在多线程编程中,如果多个线程同时对共享资源进行读写操作,就可能发生线程冲突。定时器通常会采用多线程的方式来执行定时任务,因此在执行事务时也可能存在多线程冲突的风险。 可能的冲突场景包括: 1. 同一时点有多个定时器任务需要执行,可能导致多个线程同时对共享资源进行操作,发生冲突。 2. 定时器中的任务可能访问共享数据,如果没有采取线程安全的措施,可能会导致数据不一致或者数据损坏。 3. 执行任务时可能会涉及到资源竞争,例如多线程同时对同一个文件进行写操作,就可能导致文件内容错误。 为了避免定时器执行事务时发生多线程冲突,可以采取以下措施: 1. 在共享资源访问时,使用线程同步机制,如互斥锁、信号量等,保证同一时只有一个线程对资源进行访问。 2. 使用线程安全的数据结构或者采取合适的同步措施来保证数据的一致性。 3. 尽量减小事务执行的范围,避免对共享资源的频繁读写操作。 总之,定时器执行事务时存在多线程冲突的风险,但通过合适的线程同步和数据同步措施,可以避免或者减小冲突的发生。 ### 回答3: 定时器执行事务会发生多线程冲突的可能性较小。定时器是一种工具,用于在指定的时隔或特定的时点执行特定的任务。在多线程环境下使用定时器时,每个线程独立运行,定时器的任务也是在独立的线程中执行。 多线程冲突通常发生在多个线程同时访问或修改共享数据的情况下。由于定时器任务是独立运行的,不会直接访问共享数据,所以不容易引发多线程冲突。 然而,如果定时器任务在执行过程中需要访问共享数据,那么就有可能发生多线程冲突。在这种情况下,需要采取一些线程同步措施,例如使用线程锁(Lock)或线程安全的数据结构来保护共享数据,以避免冲突问题。 总的来说,定时器执行事务不会直接导致多线程冲突,但如果任务涉及到共享数据的访问或修改,就需要注意进行合适的线程同步措施,以确保多线程的数据一致性和安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力学习的噗噗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值