思路:
操作任意表之前,先对表做备份,如果出了异常,那么还原备份。
采用kv存储 nosql存储
main函数:
public class TestDemo {
public static void main(String[] args) {
// 数据初始化
Car car = new Car();
car.setCarAge("0");
car.setCarBirth("2022-01-30");
car.setCarBrand("宝马");
car.setCarName("我的车");
car.setHeight(120l);
car.setWeight(240l);
// 入库
Update.insert("mycar", JSON.toJSON(car).toString());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出库里的结果
Object mycar = Update.get(Car.class, "mycar");
System.out.println("结果:" + mycar);
}
工具类:
// 增删改操作
public class Update {
static Logger logger = LoggerFactory.getLogger("Update的日志");
// 备份的数据 支持并发的
private static Map oldValues = new ConcurrentHashMap<>();
// 插入数据
// key代表名称
static void insert(String key, String json) {
// 备份的内容
// 从本地取
String oldJson = "";
// 备份
// 这种备份是内存备份,不可靠 不过这里用于测试 就简写了
FileInputStream fis = null;
try {
fis = new FileInputStream(Config.nowPosition + "/" + key);
byte[] result = new byte[fis.available() + 20];
fis.read(result);
oldJson = new String(result);
} catch (Exception e) {
logger.info("文件不存在,说明之前该数据为null");
oldJson = "";
}
oldValues.putIfAbsent(key, oldJson);
logger.info("oldJson = {}", oldJson);
FileOutputStream fos = null;
FileOutputStream fos1 = null;
try {
fos = new FileOutputStream(Config.nowPosition + "/" + key);
fos.write(json.getBytes(StandardCharsets.UTF_8));
// 手动制造一个异常、模拟在插入数据过程中出异常了
int i = 1 / 0;
} catch (Exception e) {
logger.info("事务出现异常,回滚");
// 老值不为空
try {
fos1 = new FileOutputStream(Config.nowPosition + "/" + key);
if (fos1 != null) {
fos1.write(oldJson.getBytes(StandardCharsets.UTF_8));
}
} catch (IOException ex) {
logger.info("事务回滚出现异常 不作处理");
}
// 老值为空 证明之前没这个文件
} finally {
try {
fos.close();
fos1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 获取数据
static Object get(Class clz, String key) {
String value = "";
FileInputStream fis = null;
try {
fis = new FileInputStream(Config.nowPosition + "/" + key);
byte[] result = new byte[fis.available()];
fis.read(result);
value = new String(result);
} catch (Exception e) {
logger.info("读取数据出现异常");
return null;
}
logger.info("value = {}", value);
if (StringUtils.isBlank(value)) {
return "";
}
return JSON.parseObject(value, clz);
}
}
备注:
创建的io流只能使用一次,比如写入操作。如果要分两次写入,需要再重新创建一个io流



