mysql对数据操作 事物_数据库事物操作

事务

什么是事务?

转账:

1. 给wc账户减1000元

2. 给wcxf账户加1000元

当给wc账户减1000元后,抛出了异常!这会怎么样呢?我相信从此之后,wc再也不敢转账了。

使用事务就可以处理这一问题:把多个对数据库的操作绑定成一个事务,要么都成功,要么都失败!

785c73a690abf41c0e5db4ff80d2608e.png

---------------------------------------------------------------------------------------------------------------------------------------------

事物的特性:ACID

*原子性:事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。

* 一致性:事务执行后,数据库状态与其它业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。

* 隔离性:隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。

*持久性:一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。

---------------------------------------------------------------------------------------------------------------------------------------------

MySQL操作事务

1. 开始事务:start transaction

2. 结束事务:commit//提交事物rollback//事物回滚

(1)事物回滚

c23565f1bf0d7bd54baf1e3543939409.png

(2)事物提交

8b3769a0dc9564e0dbbd4ed0576094bb.png

---------------------------------------------------------------------------------------------------------------------------------------------

JDBC事务

1. 开始事务:con.setAutoCommit(false);

2. 结束事务;con.commit()或con.rollback();

public classJdbc2 {public static voidmain(String[] args) {

Connection con=null;

PreparedStatement pst=null;try{

con=JDBCUtils.getConnection();//开启事物

con.setAutoCommit(false);//开启手动事物

pst=con.prepareStatement("UPDATE acction SET mun=mun-100 WHERE username=? ");

pst.setString(1, "zhangsan");

pst.executeUpdate();//人为创建异常

int index=1/0;

pst=con.prepareStatement("UPDATE acction SET mun=mun+100 WHERE username=? ");

pst.setString(1, "wangwu");

pst.executeUpdate();

con.commit();//提交事物

}catch(Exception e) {try{

con.rollback();

}catch(SQLException e1) {

e1.printStackTrace();

}

e.printStackTrace();

}finally{//关闭

JDBCUtils.createClose(null, pst, con);

}

}

}

---------------------------------------------------------------------------------------------------------------------------------------------

保存点

保存点的是可以回滚到事务中的某个位置,而不是回滚整个事务。

回滚到保存点不会结束事务。

设置保存点:Savepoint sp = con.setSavepoint();

回滚到保存点:con.rollback(sp);

public classJdbc1 {public static voidmain(String[] args) {

Connection con=null;

PreparedStatement pst=null;

Savepoint sp=null;try{

con=JDBCUtils.getConnection();

con.setAutoCommit(false);//手动开启事物

sp=con.setSavepoint();

pst=con.prepareStatement("INSERT INTO acction(username,mun) VALUES(?,?)");for(int i=1;i<=2000;i++){if(i==1002){int index=i/0;

}

pst.setString(1, "lxp");

pst.setInt(2, i);

pst.executeUpdate();if(i%1000==0){

sp=con.setSavepoint();

}

}

con.commit();//事物提交

}catch(Exception e){try{

con.rollback(sp);

con.commit();

}catch(SQLException e1) {//TODO Auto-generated catch block

e1.printStackTrace();

}//回滚事物

e.printStackTrace();

}finally{

JDBCUtils.createClose(null, pst, con) ;

}

}

---------------------------------------------------------------------------------------------------------------------------------------------

事务隔离级别

* 脏读:读到未提交

0d9e7ceaffc4a40f25451fd9c18e7742.png

* 不可重复读:两次读取不一致,读取到另一事务修改的记录

625281f65c32e24b46d9d34a2df58641.png

* 幻读:两次读取不一致,读取到另一事务插入的记录

8e78589982b4b1a2443b5c57356e9c2b.png

---------------------------------------------------------------------------------------------------------------------------------------------

四大隔离级别

* SERIALIZABLE(串行化):对同一数据的访问是串行的,即非并发的,所以不会出现任何并发问题。易出现死锁,效率太低!不可用!

* REPEATABLE READ(可重复读):防止了脏读、不可重复读,但没有防止幻读

* READ COMMITTED(读已提交):防止了脏读,但没有防止不可重复读,以及幻读

* READ UNCOMMITTED(读未提交):可能出现所有并发问题,效率最高,但不可用!

MySQL默认事务隔离级别为:REPEATABLE READ

Oracle默认事务隔离级别为:READ COMMITTED

-------------------------------------------------------------------------------------------------------------------------------------------------

MySQL设置事务隔离级别

/*查看:*/select @@tx_isolation/*设置:*/set transaction isolation level 四选一

JDBC设置事务隔离级别

con.setTransactionIsolation(四选一)

------------------------------------------------------------------------------------------------------------------------------------------------------

代码JDBCUtils代码:

需要配置dbconfig.properties文件

public classJDBCUtils {static Properties props = null;//绑定线程

static private ThreadLocal t1=new ThreadLocal();static{//加载本地配置文件

try{

InputStream in= JDBCUtils.class.getResourceAsStream("dbconfig.properties");

props= newProperties();

props.load(in);

}catch(IOException e) {

e.printStackTrace();

}//加载驱动

try{

Class.forName(props.getProperty("driverClassName"));

}catch(ClassNotFoundException e) {

e.printStackTrace();

}

}/*** 获得Connection连接

*@return*@throwsException*/

public static Connection getConnection() throwsException {

Connection conn=t1.get();if(conn==null){//加载配合

conn= DriverManager.getConnection(props.getProperty("url"),

props.getProperty("username"), props.getProperty("password"));

t1.set(conn);

}returnconn;

}/*** 关闭所有连接

*@paramrs

*@paramstatement

*@paramconn*/

public static voidcreateClose(ResultSet rs, PreparedStatement statement,

Connection conn) {try{if (rs != null)

rs.close();if (rs != null)

statement.close();if (rs != null)

conn.close();

if(t1!=null){

t1.remove();

}

}catch(Exception e) {

e.printStackTrace();

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值