1. 事务
介绍:
事务就是一个事情,组成这个事情可能有多个单元,要求这些单元,要么全都成功,要么全都不成功。
在开发中,有事务的存在,可以保证数据完整性。
mysql下怎样操作
方式1:
start transaction 开启事务
rollback 事务回滚
commit 事务提交
方式2:
show variables like '%commit%'; 可以查看当前autocommit值
在mysql数据库中它的默认值是"on"代表自动事务.
自动事务的意义就是:执行任意一条sql语句都会自动提交事务.
测试:将autocommit的值设置为off
1.set autocommit=off 关闭自动事务。
2.必须手动commit才可以将事务提交。
注意:mysql默认autocommit=on oracle默认的 autocommit=off;
jdbc下怎样操作
java.sql.Connection接口中有几个方法是用于可以操作事务
1.setAutocommit(boolean flag);
如果flag=false;它就相当于start transaction;
2.rollBack()
事务回滚。
3.commit()
事务提交
关于JdbcUtils中使用ThreadLocal
介绍
使用的目的是确保使用同一个 Connection,保证事务的原子性,同生共死
使用
1.声明一个ThreadLocal
private static final ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
2.在getConnection()方法中操作
Connection con = tl.get(); 直接从ThreadLocal中获取,第一次返回的是null.
if (con == null) {
// 2.获取连接
con = DriverManager.getConnection(URL, USERNAME, PASSWORD);
tl.set(con); //将con装入到ThreadLocal中。
}
丢失更新及锁
丢失更新问题介绍:
多个事务对统一天记录进行了操作,后提交的事务将先提交的事务覆盖了。
解决方案:
1. 悲观锁(利用数据库内部锁机制,对当前操作的数据条进行事务锁定)
共享锁:
Select * from table lock in share mode (读锁,共享锁)
排它锁:
Select * from table for update(写锁、排它锁)
update语句默认添加排它锁
2. 乐观锁(假设丢失更新不会发生)
-----------------------采用在程序中添加版本字段解决对视更新问题
Create table product (
Id int ,
Name varchar(20),
Upadatetime timestamp
);
Insert into product values (1,”冰箱”,null)
update product set name='洗衣机' where id = 1;
解决丢失更新: 在数据表添加版本字段,每次修改记录后,版本字段改变,
如果读取到的版本字段与修改时的版本字段不一致,说明别人修改了数据
连接池(源码位置day18_2)
自定义连接池
介绍:
就是创建一个容器,用于装入多个Connection对象,在使用连接对象时,
从容器中获取一个Connection,使用完成后,在将这个Connection重新
装入到容器中。这个容器就是连接池。(DataSource)也叫做数据源.
功能:
可以通过连接池获取连接对象.
优点:
节省创建连接与释放连接 性能消耗 ---- 连接池中连接起到复用的作用 ,提高程序性能
使用:
1.一个MyDataSource类,在这个类中创建一个LinkedList<Connection> ll
2.造方法中初始化List集合,并向其中装入5个Connection对象。
3.创建一个public Connection getConnection();从List集合中获取一个连接对象返回.
4. public void readd(Connection) 这个方法是将使用完成后的Connection对象重新
装入到List集合中. dbcp连接池
Dbcp连接池
介绍:dbcp是apache的一个开源连接池。要想使用DBCP连接池,要下载jar包。
使用:
导入时要导入两个commons-dbcp-1.4.jar,commons-pool-1.5.6.jar
代码中使用:
public static void main(String[] args) throws Exception{
// BasicDataSource bds = new BasicDataSource();
// bds.setDriverClassName("com.mysql.jdbc.Driver");
// bds.setUrl("jdbc:mysql:///uu");
// bds.setUsername("root");
// bds.setPassword("");
Properties properties = new Properties();
InputStream is = DbcpPool.class.getResourceAsStream("/jdbc.properties");
properties.load(is);
DataSource ds = BasicDataSourceFactory.createDataSource(properties);
Connection conn = ds.getConnection();
search(conn);
}
C3p0连接池
介绍:C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。
目前使用它的开源项目有Hibernate,Spring等。
c3p0与dbcp区别:
dbcp没有自动回收空闲连接的功能
c3p0有自动回收空闲连接功能
使用:
ComboPooledDataSource cpds = new ComboPooledDataSource();
// cpds.setDriverClass("com.mysql.jdbc.Driver");
// cpds.setJdbcUrl("jdbc:mysql:///uu");
// cpds.setUser("root");
// cpds.setPassword("");
Connection conn = cpds.getConnection();
search(conn);
tomcat 内部连接池
介绍:tomcat内置连接池使用的是dbcp。
tomcat怎样管理连接池?(配置)
要想将一个dbcp连接池让 tomcat管理,只需要创建一个context.xml配置文件,
在配置文件中配置相关信息,
<Context>
<Resource name="jdbc/EmployeeDB" auth="Container"
type="javax.sql.DataSource" username="root" password="abc"
driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql:///uu"
maxActive="8" maxIdle="4"/>
</Context>
Context.xml 文件位置
1. 在tomcat/conf/context.xml 这时这个连接池是给整个服务器使用的。
2. 在tomcat/conf/Catalina/localhost 这时这个连接池只给localhost虚拟主机使用。
3. 将context.xml文件放置在web应用的META-INF下
4. 注意:如果是全局设置,那么我们需要将数据库驱动放置在tomcat/lib目录下
内部连接池的使用:
因为是Tomcat中的连接池,so,肯定是在web 中的使用,使用时可以在Servlet中,具体代码如下
Context context = new InitialContext();
Context envCtx = (Context) context.lookup("java:comp/env"); // 固定路径
DataSource ds = (DataSource) envCtx.lookup("jdbc/EmployeeDB");
Connection conn = ds.getConnection();
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("select * from user");
while (rs.next()){
System.out.println( rs.getString("name")+ " "
+ rs.getInt("sex")+" "
+ rs.getInt("age")
);
}