在JDBC中使用事务

事务在JDBC中十分重要,不支持事务会出现许多问题。下面举两个例子,分别是不使用事务和使用事务的情况。

1.不使用事务的情况
这里举一个例子:

package jdbc7;

import java.sql.*;

public class test1 {

	public static void main(String[] args) {
		Connection c = null;
		PreparedStatement ps = null;
		try{
			Class.forName("com.mysql.jdbc.Driver");
			c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8","root","admin");
			String sql = "update hero set hp = hp +1 where id = 22";
			String sql2 = "updata hero set hp = hp -1 where id = 22";
			ps = c.prepareStatement(sql);
			ps.execute();
			ps = c.prepareStatement(sql2);
			ps.execute();
		}catch(ClassNotFoundException e) {
			e.printStackTrace();
		}catch (SQLException e) {
			e.printStackTrace();
		}finally{		
			
			if(ps != null) {
				try {
					ps.close();
				}catch(Exception e) {
					e.printStackTrace();
				}
				ps = null;
			}
			
			if(c != null) {
				try {
					c.close();
				}catch(Exception e) {
					e.printStackTrace();
				}
				c = null;
			}
		}
	}
}

上述程序是没有使用事务的情况,假设业务操作是:加血,减血各做一次,结束后,英雄的血量不变。而减血的SQL不小心写错写成了 updata(而非update),那么最后结果是血量增加了,而非期望的不变。

执行前表中第22行:
在这里插入图片描述
执行之后:
在这里插入图片描述
和期望的血量不变产生差异,那么如何来避免这种情况的发生呢?这里就需要使用事务

2.使用事务
同样是刚才的程序,也是这些加血见血操作,也是把update写错,产生的结果却截然不同

package jdbc7;
import java.sql.*;
public class test2 {

	public static void main(String[] args) {
		Connection c = null;
		Statement s = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8\",\"root\",\"admin");
			s = c.createStatement();
			c.setAutoCommit(false);
			
			String sql1 = "update hero set hp = hp +1 where id = 22";
            s.execute(sql1);
            
            String sql2 = "updata hero set hp = hp -1 where id = 22";
            s.execute(sql2);
            
            c.commit();
		}catch(ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{		
			
			if(s != null) {
				try {
					s.close();
				}catch(Exception e) {
					e.printStackTrace();
				}
				s = null;
			}
			
			if(c != null) {
				try {
					c.close();
				}catch(Exception e) {
					e.printStackTrace();
				}
				c = null;
			}
		}
	}
}

运行结果:
在这里插入图片描述
血量没有发生变化,符合预期。
总结:
在事务中的多个操作,要么都成功,要么都失败
通过 c.setAutoCommit(false);关闭自动提交
使用 c.commit();进行手动提交。
所以,虽然第一条SQL语句是可以执行的,但是第二条SQL语句有错误,其结果就是两条SQL语句都没有被提交。 除非两条SQL语句都是正确的。

猜你喜欢

转载自blog.csdn.net/qq_41998938/article/details/89739742