MySql事务
Posted 晓锋残月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySql事务相关的知识,希望对你有一定的参考价值。
一、为什么会引入事务概念
在银行转账系统中进场会遇见一个现象,那便是如果A给B转账,但是转账的中间过程出了问题,导致A转账失败,但是B却得到了钱,因而出现了错误。下面使用简单的例子证明。
假设某数据库有数据如下:
新建一个Java项目,在里面写入下面代码:
得到的结果为:
上面的问题是:张三给李四转账了,但是由于中间过程出错,导致转账失败,导致李四没收到钱。
二、事务的应用
1、事务的概念
事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部不成功。
2、mysql事务
a、mysql引擎是支持事务的
b、mysql默认自动提交事务。每条语句都处在单独的事务中。
c、手动控制事务
开启事务:start transaction | begin
提交事务:commit
回滚事务:rollback
下面以简单的例子来手动控制事务
(1)begin--commit,事务开启提交
查看数据库得到结果为:
(2)begin--rollback 进行事务回滚
得到的结果为:
3.JDBC中应用事务
在上面是在客户端进行事务处理,下面介绍的将是事务在jdbc中的应用
将上面的第一个代码修改为如下所示
package com.xfcy.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.junit.Test;
import com.xfcy.utils.DBUtils;
public class TestDemo01
@Test
public void test1()
Connection conn=null;
PreparedStatement ps=null;
try
conn=DBUtils.getConnection();
conn.setAutoCommit(false);//其作用相当于begin
ps=conn.prepareStatement("update testone set money=money-100 where name='张三'");
ps.executeUpdate();
ps=conn.prepareStatement("update testone set money=money+100 where name='李四'");
ps.executeUpdate();
conn.commit();//提交事务commit
catch (Exception e)
if(conn!=null)
try
conn.rollback();//进行事务回滚
catch (SQLException e1)
e1.printStackTrace();
e.printStackTrace();
finally
DBUtils.closeAll(null, ps, conn);
查看数据库结果为:
三、事务的基本性质
原子性:指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态。转账前和转账后的总金额不变。
隔离性:事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性:指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。四、事务的隔离级别
如果多个进程并发,则会导致下面的问题。1、赃读:指一个事务读取了另一个事务未提交的数据
2、不可重复读:在一个事务内读取表中的某一行数据,多次读取结果不同。一个事务读取到了另一个事务提交后的数据。
3、 虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。 (insert)
为了解决上面的问题发生,可以通过设置事务隔离级别完成。 * 1、READ UNCOMMITTED: 赃读、不可重复读、虚读都有可能发生。
* 2、READ COMMITTED: 避免赃读。不可重复读、虚读都有可能发生。(oracle默认的)
* 4、REPEATABLE READ:避免赃读、不可重复读。虚读有可能发生。(mysql默认)
* 8、SERIALIZABLE: 避免赃读、不可重复读、虚读。
级别越高,性能越低,数据越安全
查看当前事务隔离级别: SELECT @@TX_ISOLATION;
查看当前数据库隔离级别
通过查询可以知道当前MySQL级别为:REPEATABLE READ
更改当前事务隔离界别: SET TRANSACTION ISOLATION LEVEL+(read uncommitted等),注意;设置隔离级别必须在事务前。
在jdbc中设置隔离级别
设置隔离级别必须在开启事务之前进行。
Connection.setTransactionIsolation(int level);
而leve的值为:
①TRANSACTION_READ_COMMITTED:指示不可以发生脏读的常量;不可重复读和虚读可以发生。
②TRANSACTION_READ_UNCOMMITTED:指示可以发生脏读 (dirty read)、不可重复读和虚读 (phantom read) 的常量
③TRANSACTION_REPEATABLE_READ:指示不可以发生脏读和不可重复读的常量;虚读可以发生。
④TRANSACTION_SERIALIZABLE:指示不可以发生脏读、不可重复读和虚读的常量。
总结
通常情况下,对于数据库的隔离级别不需要更改,对于这些知识更更多的是需要理解。上面便是个人对数据库事务的学习,如果有任何错误,希望提出,谢谢!
以上是关于MySql事务的主要内容,如果未能解决你的问题,请参考以下文章