Syong : 事务(Transaction)

事务(Transaction)

What

数据库事务(百度百科):

数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。

Java事务(Oracle官网):

Transactions in Java EE Applications. In a Java EE application, a transaction is a series of actions that must all complete successfully, or else all the changes in each action are backed out. Transactions end in either a commit or a rollback.

译:
在Java EE应用程序中,事务是一系列必须全部成功完成的操作,否则将撤消每个操作中的所有更改。事务以提交或回滚结束。

Before
为什么上面提到了数据库事务还有java事务呢?通常我们刚开始接触的时候,默认事务就是数据库事务,但是在javaweb开发中,很多时候我们接触到的是java事务,虽然有些许区别,但是核心都是一样的,也就是:(ACID),不同的只是我们会用java代码去控制事务。

What
要了解事务,首先要了解事务的四大特性:ACID

  1. A(Atomicity):原子性:对数据的一系列更改都像执行单个操作一样执行,要么全部执行,要么全部不执行
  2. C(Consistency):一致性:事务开始和结束时,数据处于一致状态。
  3. I(Isolation):隔离性:事务的中间状态对于其他事务是不可见的。 结果,同时运行的事务似乎已被序列化。也就是说,事务与事务之间是互不干扰的;
  4. D(Durability):持久性:事务一旦被提交,它对数据的修改既是永久性的,不可回滚不可修改

事务的ACID特性是由关系数据库系统(DBMS)来实现的,DBMS采用日志来保证事务的原子性、一致性和持久性。日志记录了事务对数据库所作的更新,如果某个事务在执行过程中发生错误,就可以根据日志撤销事务对数据库已做的更新,使得数据库同滚到执行事务前的初始状态。
对于事务的隔离性,DBMS是采用锁机制来实现的。当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。

如果说开发的系统是比较简单的,基本没有什么业务量/并发量,甚至是一个demo,那么这个时候很难体现出事务的特性,因为对于系统跟数据库来说,每一个事务的隔离级别都相当于是序列化(Serializable),关于隔离级别下面再提出,这里要提出的问题是:
高并发下,事务可能会带来的一些问题

  1. 第一类丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖;
  2. 第二类丢失更新:两个事务同时操作一个数据,先提交的被后提交的覆盖;
  3. 脏读:事务A读取到事务B未提交的数据;
  4. 不可重复读:在一个事务中,两次读取同一数据结果不同;
  5. 幻读:一个事务里面的操作中发现了未被操作的数据

接下来,如何解决这些问题呢?这里我们就要提到事务的隔离级别:(由低到高排序)

  1. Read_uncommited:最低级别,任何情况都无法保证;
  2. Read_commited:一个事务要等到另一个事务提交后才能读取数据,可避免脏读的发生;
  3. Repeatable_read:开始读取数据(事务开启)时,不再允许修改操作;可避免脏读与不可重复读;
  4. Serializable:只允许一个事务在执行,其它事务必须等待这个事务执行完后才能执行。可避免幻读。

用mysql做一个比较好的展示:展示

以上最近提到的4点中的2,3,4,可以避免脏读/不可重复读/幻读;

第一类丢失更新:也就是回滚覆盖,目前主流数据库支持的所有的隔离级别基本杜绝了第一类数据更新丢失的问题;

第二类丢失更新比较特殊,这是另外一个话题了(如何解决第二类丢失更新,总结有提到)。

总结:

1.第一类丢失更新,由数据库去杜绝;
2.第二类丢失更新 与 脏读/不可重复读/幻读 的区别是,前者是两个以上事务同时开始的时候,都结束的情况下可能会发生情况;后者是两个以上事务同时开始的时候,至少还有一个没结束可能会发生的情况;
3.脏读/不可重复读/幻读,可以通过设置数据库的隔离级别去避免;
4.Serializable可以解决,第二类丢失更新,但是代价太大,如果有需要的话,可以通过增加版本号机制,或代码层面加锁等方式去控制其串行化执行。

After
上面介绍了数据库事务,接下来稍微介绍一下java事务,主要有以下几种:

  1. JDBC(Java DataBase Connection)事务(单库)
  2. JTA(Java Transaction API)事务(多库)
  3. Spring容器事务

这里有一篇博客写的不错:Java中的事务及使用

Other
与事务有关的一个重要领域:分布式事务。,请自行百度

在查找资料的过程中,找到一些写得不错的博客

大家可以参考参考。Java Spring 与数据库中的事务(transaction)

End
结束语:优秀是一种习惯。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]和\[2\]提供了关于ThreadLocal的一些信息。ThreadLocal是一个用于在多线程环境下存储线程本地变量的工具类。每个线程都有一个threadLocals参数,它是一个ThreadLocal.ThreadLocalMap类型的对象,用于存储线程本地变量。\[1\]\[2\]引用的代码片段展示了ThreadLocal的一些作,包括创建ThreadLocal对象、将值存储到ThreadLocalMap中以及从ThreadLocalMap中获取值。 在问题中提到了ThreadLocalHelper,但是没有提供具体的引用内容。根据问题描述,ThreadLocalHelper可能是一个自定义的工具类,用于帮助管理ThreadLocal对象。然而,由于没有提供更多的信息,无法给出更具体的回答。 ThreadLocal在实际应用中有很多用途,如声明式事务中的数据库连接管理、拦截器中的用户信息存储等。通过将对象存储在ThreadLocal中,可以实现线程间的数据隔离,每个线程都可以独立地访问和修改自己的ThreadLocal变量,而不影响其他线程的数据。这在多线程环境下非常有用。 总结起来,ThreadLocal是一个用于在多线程环境下存储线程本地变量的工具类,通过ThreadLocalMap实现。它可以帮助实现线程间的数据隔离,每个线程都可以独立地访问和修改自己的ThreadLocal变量。ThreadLocalHelper可能是一个自定义的工具类,但由于缺乏具体信息,无法给出更详细的解释。 #### 引用[.reference_title] - *1* *2* [Syong : ThreadLocal](https://blog.csdn.net/CSY_LOVE_GYY/article/details/103236361)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [ThreadLocal及强软弱虚引用](https://blog.csdn.net/qq_43583755/article/details/121269598)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值