每博一文案
看过这样一句话,时间在不断的筛选你身边的人和事。当你什么都不在乎的时候,你的人生才刚刚开始。
当我们什么都不在乎时,会发现什么都可能会进行经历,但什么都一定会过去,起始都会离开的或早或晚吧了。
道德经中说:“飘风不终朝,骤雨不终日“,生活本来没有那么沉重,一味的与自己较劲,只会作茧自缚,
折磨你的从来不是任何热的情绪,而是你心存幻想的期待。
世间万物都在治愈你,但唯独你自己,不可放过自己,你涉水而过,但不代表拥有这条河,越是执着,哪些
给你带来快乐的人,事,物,其带来的痛苦就越大,不要把怀念,弄得比过程还长。
怀念时一种惩罚,惩罚哪些喜欢念旧的人。要知道钟表能回到起点,但是回不到昨天,你应该让自己变好,
而不是沉寂在,这段不闻不问的日子里,与其纠结往事,越陷越深,不如试着与它和解,别和往事过不去,因为他已经过去,别和现实过不去,因为你还要过下去,意味的偏执,往往会将自己的救赎越埋越深。
世上千灯万盏,不如心灯一盏。心若盛开,一念起风声鹤唳,一念灭繁花似锦。
大风遥遥,有人告别,有人伫立。暮色长凝,有人点灯,有人熄。花开花落自有时,别问这人间值不值得。
安然过冬,来年一定又是好春光。
愿你得失随缘,自在随心,往事的背后疗伤,在人来人往中坚强。
—————— 一禅心灵庙语1
文章目录
悲观锁
顾名思义,就是比较悲观的锁,总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。
在Mysql当中只需要在 select 查询的结果后面加上 for update
其查询的结果就被锁上了。如果本次事务没有被 commit
提交给数据库,则其他事务就无法修改:下面我们对 tests 数据表进行一个悲观锁的控制
下面是两段Java中使用悲观锁的演示:
package Blogs.blogs04;
import java.sql.*;
public class LockTest {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null; // 扩大作用域,用于关闭资源
try {
// 1. 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2.连接驱动中的数据库,url中的 localhost 可以省略为 ///dbtest
connection = DriverManager.getConnection("jdbc:mysql:///dbtest6","root","MySQL123");
connection.setAutoCommit(false); // 取消自动提交数据,开启事务
// 3. 获取操作数据库的(预编译)对象
String sql = "select id,name from tests where id = ? for update"; // for update 悲观锁
preparedStatement = connection.prepareStatement(sql); // 预编译对象
// 填充占位符
preparedStatement.setInt(1,1); // 占位符的填充从起始下标 1 开始
// 4.执行sql语句
resultSet = preparedStatement.executeQuery();
// 处理select 查询的结果集
while(resultSet.next()) { // 判断该行记录是否有数据有,返回true并向下移动,没有返回false
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
System.out.println(id+"=>"+name);
}
connection.commit(); // 手动提交数据信息
} catch (Exception e) {
if(connection != null) {
// 出现异常,回滚事务
try{
connection.rollback(); // 事务的回滚
} catch(SQLException E) {
throw new RuntimeException (E); // 将编译异常转换为运行异常抛出
}
}
throw new RuntimeException (e); // 将编译异常转换为运行异常抛出
} finally {
// 6.关闭资源,最晚使用的最先关闭
if(resultSet != null) { // 防止空引用
try{
resultSet.close(); // 释放处理select 查询结果集的资源
}catch(SQLException e) {
throw new RuntimeException (e); // 将编译异常转换为运行异常抛出
}
}
if(preparedStatement != null) {
try{
preparedStatement.close(); // 释放操作数据库的资源
} catch (SQLException e) {
throw new RuntimeException (e); // 将编译异常转换为运行异常抛出
}
}
if(connection != null) {
try {
connection.close(); // 关闭数据库连接
} catch (SQLException e) {
throw new RuntimeException (e); // 将编译异常转换为运行异常抛出
}
}
}
}
}
package Blogs.blogs04;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class LockTest2 {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null; // 扩大作用域,用于关闭资源
try {
// 1. 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2.连接驱动上的数据库
connection = DriverManager.getConnection("jdbc:mysql:///dbtest6","root","MySQL123");
connection.setAutoCommit(false); // 取消自动提交数据,开启事务
// 3. 获取到操作数据库的对象(预编译sql语句对象)
String sql = "update tests set name = ? where id = ?"; // 占位符不要加单引号,不然就成字符串了
preparedStatement = connection.prepareStatement(sql); // 仅仅只是预编译sql语句
// 填充占位符(在预编译之后,防止sql注入),起始下标是从 1 开始的
preparedStatement.setString(1,"Tom");
preparedStatement.setInt(2,1);
// 4.执行sql语句
int count = preparedStatement.executeUpdate(); // 返回影响数据库的行数(注意是无参的,因为上面我们已经编译过了)
System.out.println("影响数据库的行数: "+count);
connection.commit(); // 手动提交数据
// 5. 处理select 查询的结果集,这里不是
} catch (Exception e) {
// 发生异常,回滚事务
if(connection != null) { // 防止null引用
try {
connection.rollback();
} catch (SQLException E) {
throw new RuntimeException (E); // 将编译异常转换为运行异常抛出
}
}
throw new RuntimeException (e); // 将编译异常转换为运行异常抛出
} finally {
// 6.关闭资源,最晚使用的最先关闭资源
if(preparedStatement != null) {
try{
preparedStatement.close(); // 释放操作数据库的资源
} catch (SQLException e) {
throw new RuntimeException (e); // 将编译异常转换为运行异常抛出
}
}
if(connection != null) {
try {
connection.close(); // 关闭数据库连接
} catch (SQLException e) {
throw new RuntimeException (e); // 将编译异常转换为运行异常抛出
}
}
}
}
}
总结:
悲观锁:如果一个 select 查询的结果集附加上 for update
(就会被悲观锁,锁住),当这个事务没有手动提交 commit 数据结束,其他事务是无法对 select 查询结果集锁住的数据进行一个修改的,但只有悲观锁的事务 commit 提交了,就可以更改了。
最后:
限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵——多多益善,谢谢大家,后会有期,江湖再见 !!!。最后,朋友,请留下你来过的证明 。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/83005.html