深入浅出了解java事务-07

139 阅读6分钟

1、什么是事务

事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。

2、事务的4个特性(ACID)

  1. 原子性(atomicity):事务是数据库的逻辑工作单位,而且是必须是原子工作单位,对于其数据修改,要么全部执行,要么全部不执行。
  2. 一致性(consistency):事务在完成时,必须是所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。(实例:转账,两个账户余额相加,值不变。)
  3. 隔离性(isolation):一个事务的执行不能被其他事务所影响。
  4. 持久性(durability):一个事务一旦提交,事物的操作便永久性的保存在DB中。即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

3、 Java有几种类型的事务

Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、spring容器事务

4、事务的隔离级别

20190419130920994.png

当我们有多个客户端同时操作数据库的某张表时,如何进行隔离操作?MySQL提供了隔离级别。当MySQL表被多个线程或者客户端开启各自事务操作数据库中的数据时,MySQL提供了一种机制,可以让不同的事务在操作数据时,具有隔离性。从而保证数据的一致性。

幻读和不可重复读的概念类似,都是不同时间数据不一致,只不过幻读是针对新增数据,而不可重复读是针对更改数据。
`1.脏读:  一个事务读到另一个事务未提交的更新数据。

2.不可重复读:  一个事务两次读同一行数据,可是这两次读到的数据不一样。

3.幻读:  一个事务执行两次查询,但第二次查询比第一次查询多出了一些数据行。
脏读(Drity Read): 已知有两个事务A和B, A读取了已经被B更新但还没有被提交的数据,之后,B回滚事务,A读取的数据就是脏数据。 例子:银行卡原有1000元,A向银行卡转账1000元,B读到2000元,A发现转错了,B回滚事务后A再查询结果又变成1000元,之前读到的2000元就是脏数据

不可重复读(Non-repeatable read): 已知有两个事务A和B,A 多次读取同一数据,B 在A多次读取的过程中对数据作了修改并提交,导致A多次读取同一数据时,结果不一致。

幻读(Phantom Read): 已知有两个事务A和B,A从一个表中读取了数据,然后B在该表中插入了一些新数据,导致A再次读取同一个表, 就会多出几行,简单地说,一个事务中先后读取一个范围的记录,但每次读取的纪录数不同,称之为幻读

小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。

4.1 脏读

1、张三的原工资是1000,财务人员将张三的工资改为8000,但是未提交事务 2、张三读取自己的工资,发现是8000,欣喜若狂 3、财务发现操作有误,回滚了事务,张三的工资又变为1000 像这样,张三读取的工资数是8000就是一个脏数据

4.2 不可重复读

是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(即不能读到相同的数据内容) 在事务1中,张三读取自己的工资为1000,操作并没有完成 在事务2中,财务将张三的工资改为2000,并提交了事务 在事务1中,张三再次读取自己的工资时,工资变为了2000 解决办法:如果只有在修改事务完全提交之后才可以读数据,则可以避免该问题 不可重复读的重点是修改:同样的条件, 你读取过的数据,再次读取出来发现值不一样了

4.3 幻读

是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。 目前工资为1000的员工有10人 1、事务1,读取所有工资为1000的员工 2、事务2,向表中插入一条员工记录,工资为1000 3、事务1读取所有工资为1000的员工,读取了11条记录 解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,则可以避免该问题 幻读的重点在于新增或者删除:同样的条件, 第1次和第2次读出来的记录数不一样

5、update语句

5.1、update set where id = 1和update set where id >1分别用了什么锁

6、串行化和重复读相比加了什么锁

7、分布式事务的核心代码实现