做网站图片知识,知名企业网站搭建品牌,长春手机网站建站,网站的建设方式有哪些/*########事务数据库连接池DBUtils ######事务 Transaction 其实指的一组操作#xff0c;里面包含许多个单一的逻辑。只要有一个逻辑没有执行成功#xff0c;那么都算失败。 所有的数据都回归到最初的状态(回滚) ####为什么要有事务? 为了确保逻辑的成功… /*########事务数据库连接池DBUtils ######事务 Transaction 其实指的一组操作里面包含许多个单一的逻辑。只要有一个逻辑没有执行成功那么都算失败。 所有的数据都回归到最初的状态(回滚) ####为什么要有事务? 为了确保逻辑的成功。 例子 银行的转账。 ###使用命令行方式演示事务。 * 开启事务 start transaction;* 提交或者回滚事务 commit; 提交事务 数据将会写到磁盘上的数据库 rollback ; 数据回滚回到最初的状态。1. 关闭自动提交功能。 2. 演示事务 #####使用代码方式演示事务 代码里面的事务主要是针对连接来的。 1. 通过conn.setAutoCommitfalse 来关闭自动提交的设置。 2. 提交事务 conn.commit(); 3. 回滚事务 conn.rollback();//注意当数据库不支持回滚的时候有如下原因 * 1.数据库引擎不是innodb 而是myisam不支持事务回滚。 * 2.在rollback之前 已经通过connection.commit 提交改动 无法回滚 * 3.mysql默认create drop alter 等涉及到表修改会隐式结束当前会话中的任何活动事务直接提交无法回滚。 Test public void testTransaction(){ Connection conn null; PreparedStatement ps null; ResultSet rs null; try { conn JDBCUtil.getConn(); //连接事务默认就是自动提交的。 关闭自动提交。 conn.setAutoCommit(false); String sql update account set money money - ? where id ?; ps conn.prepareStatement(sql); //扣钱 扣ID为1 的100块钱 ps.setInt(1, 100); ps.setInt(2, 1); ps.executeUpdate(); int a 10 /0 ; //加钱 给ID为2 加100块钱 ps.setInt(1, -100); ps.setInt(2, 2); ps.executeUpdate(); //成功 提交事务。 conn.commit(); } catch (SQLException e) { try { //事变 回滚事务 conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); }finally { JDBCUtil.release(conn, ps, rs); } } ###事务的特性 * 原子性 指的是 事务中包含的逻辑不可分割。 * 一致性 指的是 事务执行前后。数据完整性 * 隔离性 指的是 事务在执行期间不应该受到其他事务的影响 * 持久性 指的是 事务执行成功那么数据应该持久保存到磁盘上。 ###事务的安全隐患 不考虑隔离级别设置那么会出现以下问题。 * 读 脏读 不可重读读 幻读. * 脏读 一个事务读到另外一个事务还未提交的数据 * 不可重复读 一个事务读到了另外一个事务提交的数据 造成了前后两次查询结果不一致。 ####读未提交 演示1. 设置A窗口的隔离级别为 读未提交 2. 两个窗口都分别开启事务 * 写 丢失更新 #### 读已提交演示 1. 设置A窗口的隔离级别为 读已提交 2. A B 两个窗口都开启事务 在B窗口执行更新操作。 3. 在A窗口执行的查询结果不一致。 一次是在B窗口提交事务之前一次是在B窗口提交事务之后。 这个隔离级别能够屏蔽 脏读的现象 但是引发了另一个问题 不可重复读。 ###可串行化 如果有一个连接的隔离级别设置为了串行化 那么谁先打开了事务 谁就有了先执行的权利 谁后打开事务谁就只能得着等前面的那个事务提交或者回滚后才能执行。 但是这种隔离级别一般比较少用。 容易造成性能上的问题。 效率比较低。 * 按效率划分从高到低 读未提交 读已提交 可重复读 可串行化 * 按拦截程度 从高到底 可串行化 可重复读 读已提交 读未提交 ##事务总结 ###需要掌握的1. 在代码里面会使用事务 conn.setAutoCommit(false); conn.commit(); conn.rollback(); 2. 事务只是针对连接连接对象如果再开一个连接对象那么那是默认的提交。 3. 事务是会自动提交的。 ###需要了解的 ####安全隐患 读 脏读 一个事务读到了另一个事务未提交的数据 不可重复读 一个事务读到了另一个事务已提交的数据造成前后两次查询结果不一致 幻读 一个事务读到了另一个事务insert的数据 造成前后查询结果不一致 。 写 丢失更新。 ####隔离级别 读未提交 引发问题 脏读 读已提交 解决 脏读 引发 不可重复读 可重复读 解决 脏读 、 不可重复读 未解决 幻读 可串行化 解决 脏读、 不可重复读 、 幻读。 mySql 默认的隔离级别是 可重复读Oracle 默认的隔离级别是 读已提交 ###丢失更新 ###解决丢失更新* 悲观锁 可以在查询的时候加入 for update数据库的锁的机制排他锁 * 乐观锁 要求程序员自己控制。 select tx_isolation查看现在的隔离级别(数据库)set session transaction isolation level read XXX;修改隔离等级(数据库)XXXX参数:uncommitted 读未提交committed 读已经提交read 重复度serializable 可串行化 */ 数据库连接代码: import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class ConnLink {
//数据库的连接部分public String jdbc_drivercom.mysql.jdbc.Driver;public String jdbc_connjdbc:mysql://localhost:3306/test;public String userroot;public String passroot;//返回连接函数的部分public Connection getConn() throws SQLException, ClassNotFoundException{//1.注册驱动Class.forName(jdbc_driver);//2.获取连接Connection connectionDriverManager.getConnection(jdbc_conn,user,pass);return connection;}//释放连接资源的部分public void relese(Connection conn,PreparedStatement pstmt) throws SQLException{if(pstmt!null) pstmt.close();if(conn!null) conn.close();}
} 演示代码: import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.jsp.tagext.TryCatchFinally;public class Transaction {static ConnLink connlinknew ConnLink();public static void main(String[] args) throws SQLException, ClassNotFoundException {Connection connnull;PreparedStatement pstmtnull; try {//获取数据库的连接connconnlink.getConn();//连接事务默认就是自动提交的。 关闭自动提交。conn.setAutoCommit(false);//创建执行sql语句的对象3 书写sql语句;String sqlStringupdate blank set money money - ? where id ?;//创建预处理对象pstmt conn.prepareStatement(sqlString);//设置参数占位符pstmt.setInt(1, 100);pstmt.setInt(2,1); //执行语句pstmt.executeUpdate();//以上部分是给用户1扣100元我们可以理解是用户1给用户2转账100元。所以下面要给用户2增加100元//在此处设置一个错误促使数据库的事件回滚int a10/0;String sqlString2update blank set money money ? where id ?;pstmt conn.prepareStatement(sqlString2);pstmt.setInt(1, 100);pstmt.setInt(2,2); pstmt.executeUpdate();//由于上面的conn.setAutoCommit(false);设置成了flase所以此处需要用commit()进行提交conn.commit();} catch (SQLException e) {// TODO: handle exception//这里是出现意外的情况就是转账失败那么怎么办呢直接取消所有的操作实现数据库的回滚。conn.rollback();e.printStackTrace();}finally{connlink.relese(conn, pstmt);}}
} 转载于:https://www.cnblogs.com/byczyz/p/11343280.html