PostgreSQL TCL(事务控制语言)深度详解文档

Oracle中SQL与PL/SQL选型决策:声明式vs过程式执行模型深度解析 SQL是基于关系代数的声明式查询语言,核心在于描述‘要什么结果’,由优化器自动选择最优执行路径;PL/SQL则是嵌入数据库内核的过程式运行时,支持变量、循环、异常和事务控制,适用于多步强一致业务逻辑。二者本质差异不在语法,而在执行模型——SQL运行于共享池的声明式契约层,PL/SQL则直接调度PGA内存与事务引擎。技术价值体现在性能(减少网络往返、批量DML)、一致性(原子事务封装)与可维护性(模块化包结构)。典型场景包括报表查询(优先SQL+物化视图)、资金结算(必须PL/SQL保障ACID)、ETL清洗 阅读详情

以下是专为 Java 后端开发者(尤其是使用 Spring Boot 的团队)撰写的 PostgreSQL TCL(事务控制语言)深度详解文档,全面覆盖定义、作用、核心语句、企业级最佳实践、常见陷阱、与 Java 事务注解的映射关系,并提供标准、完整、带中文注释的实战示例,可直接作为团队事务规范、代码审查标准与培训教材。


🔄 PostgreSQL TCL(事务控制语言)深度详解文档

—— 数据一致性的“守护神”与业务可靠性的基石

适用对象:Java 开发、后端架构师、技术负责人、测试工程师、DBA
目标:系统掌握 PostgreSQL TCL 的所有核心机制与企业级事务实践,统一团队事务使用规范,杜绝“脏读”“幻读”“数据不一致”“死锁”“性能灾难”,实现原子性、一致性、隔离性、持久性(ACID) 的高可靠数据操作。


一、TCL 是什么?(Definition)

TCL(Transaction Control Language,事务控制语言)是用于管理数据库事务的生命周期的 SQL 子集。
它不操作数据内容,而是控制一组 DML 操作是否作为一个整体成功提交或整体回滚。

✅ 核心作用:

作用说明
保证原子性一组操作要么全部成功,要么全部失败(如:扣款 + 记账)
确保一致性事务前后,数据必须满足业务约束(如:账户余额不能为负)
控制隔离性多个事务并发执行时,避免互相干扰(脏读、不可重复读、幻读)
保障持久性事务一旦提交,数据永久写入磁盘,即使系统崩溃也不丢失
支持回滚与恢复出错时撤销所有中间状态,恢复到事务开始前

💡 关键认知:

  • 没有事务的数据库,就是一堆会写入的文件。
  • 一条 UPDATE 没有事务,可能只执行一半,导致数据错乱;
  • 一个“下单”操作涉及:扣库存、创建订单、加积分、发消息——必须用事务包裹。
  • 在 Java 中,我们用 @Transactional,但必须理解其背后的 TCL 机制,否则就是“黑盒编程”。

二、TCL 包含哪些内容?(Core Components)

PostgreSQL 的 TCL 主要包含以下四类语句:

语句中文名称作用企业级重要性
✅ BEGIN / START TRANSACTION开启事务显式启动一个事务块开发中较少直接使用,Spring 会自动开启
✅ COMMIT提交事务将事务中所有修改永久写入数据库必须成功,否则数据丢失
✅ ROLLBACK回滚事务撤销事务中所有未提交的修改关键错误恢复机制
✅ SAVEPOINT设置保存点在事务内创建可部分回滚的锚点高级场景,用于复杂流程的局部恢复
✅ ROLLBACK TO SAVEPOINT回滚到保存点撤销自保存点以来的操作与 SAVEPOINT 配合使用

⚠️ 注意:

  • BEGIN 和 START TRANSACTION 是同义词。
  • PostgreSQL 默认自动提交模式(autocommit),每条 SQL 独立成事务。
  • 企业开发中,必须显式控制事务边界,禁用自动提交。

三、TCL 核心语句详解与企业级标准示例(带中文注释)

以下所有示例均为生产环境推荐写法,遵循 PostgreSQL 最佳实践与 Java 团队协作规范。


✅ 1. BEGIN / START TRANSACTION —— 显式开启事务(生产环境推荐)

✅ 原则:
在 Java 中,通常由 @Transactional 自动开启,但理解其底层行为至关重要。

-- 📌 示例1:显式开启事务(用于调试或 DBA 手动操作)
BEGIN;  -- ✅ 开启一个事务块,后续所有操作都在此事务内

-- 执行多个 DML 操作
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE user_id = 2;

-- ✅ 此时数据尚未写入磁盘,仅存在于内存事务缓冲区
-- 如果此时断电,这两个更新都会消失

-- 如果一切正常,提交事务
COMMIT;  -- ✅ 所有修改永久生效

-- 如果出错,回滚事务
-- ROLLBACK;  -- ✅ 撤销所有操作,恢复原状

✅ 团队规范建议:

  • 生产环境禁止手动写 BEGIN / COMMIT,应由 Spring 自动管理。
  • 在 psql 或工具中调试时,务必使用 BEGIN + COMMIT/ROLLBACK,避免误操作污染数据。
  • 永远不要在生产环境关闭 autocommit 后不提交或不回滚,会导致连接被锁死。

✅ 2. COMMIT —— 提交事务(成功终点)

✅ 原则:
只有 COMMIT 成功,数据才真正持久化。
COMMIT 是事务的“最终确认”。

-- 📌 示例1:成功提交转账事务
BEGIN;

-- 扣款
UPDATE accounts SET balance = balance - 500 WHERE user_id = 1001;

-- 充值
UPDATE accounts SET balance = balance + 500 WHERE user_id = 1002;

-- 记录交易日志
INSERT INTO transactions (from_user, to_user, amount, status, created_at)
VALUES (1001, 1002, 500, 'success', NOW());

-- ✅ 所有操作均成功,提交事务
COMMIT;  -- ✅ 此时数据才真正写入磁盘,其他会话可见

-- ✅ 提交后,事务结束,自动进入 autocommit 模式

✅ 团队规范建议:

  • 所有 @Transactional 方法,必须成功执行完毕才提交。
  • 不要在事务中执行耗时操作(如调用外部 API、发送邮件),避免事务长时间挂起。
  • COMMIT 是原子性终点,一旦提交,无法撤销。

✅ 3. ROLLBACK —— 回滚事务(失败救生舱)

✅ 原则:
任何异常、错误、校验失败,都必须触发 ROLLBACK。
这是数据一致性的最后一道防线。

-- 📌 示例1:转账失败,自动回滚
BEGIN;

-- 扣款
UPDATE accounts SET balance = balance - 500 WHERE user_id = 1001;

-- 充值:目标账户不存在!
UPDATE accounts SET balance = balance + 500 WHERE user_id = 999999;  -- ❌ 无此用户,报错!

-- ✅ 此时系统抛出异常(如:无此用户)
-- PostgreSQL 自动回滚整个事务(如果未手动 COMMIT)
ROLLBACK;  -- ✅ 手动回滚,确保扣款也被撤销

-- ✅ 事务结束后,两个账户余额均恢复原状,无数据损坏

✅ Java 中对应场景:

@Transactional
public void transferMoney(Long fromUserId, Long toUserId, BigDecimal amount) {
    accountService.debit(fromUserId, amount);  // ✅ 扣款
    accountService.credit(toUserId, amount);   // ✅ 充值

    // 如果 credit 抛出异常(如用户不存在)
    // Spring 会自动触发 ROLLBACK,debit 操作也会被撤销
}

✅ 团队规范建议:

  • 任何业务校验失败(余额不足、状态错误、外部服务超时)都必须抛出异常,触发回滚。
  • 禁止在事务中 catch 异常后不重新抛出,会导致事务被“静默提交”。
  • 使用 @Transactional(rollbackFor = Exception.class) 明确回滚范围。

✅ 4. SAVEPOINT + ROLLBACK TO SAVEPOINT —— 局部回滚(高级控制)

✅ 适用场景:
在一个大事务中,部分步骤失败时,只回滚该部分,保留前面成功操作。

-- 📌 示例:创建订单 + 发送通知 + 扣库存(三步,允许部分失败)

BEGIN;

-- 步骤1:创建订单(必须成功)
INSERT INTO orders (user_id, order_no, total_amount, status)
VALUES (1001, 'ORD-20251017-001', 299.90, 'pending')
RETURNING id INTO order_id;  -- ✅ 获取订单ID(伪代码,实际用 RETURNING)

-- ✅ 设置保存点1:订单已创建,可回滚至此
SAVEPOINT sp_order_created;

-- 步骤2:扣库存(可能失败,但订单已存在)
UPDATE products SET stock = stock - 1 WHERE id = 101;
-- ❌ 假设库存不足,抛出异常

-- ✅ 此时,我们不想删除订单,只想回滚库存操作
ROLLBACK TO SAVEPOINT sp_order_created;  -- ✅ 回滚到保存点,撤销库存更新

-- ✅ 但订单仍然存在!继续下一步
UPDATE products SET stock = stock - 1 WHERE id = 102;  -- ✅ 改为扣另一个商品库存,成功

-- 步骤3:发送通知(外部调用,可能失败)
-- 假设通知服务超时,抛出异常
-- 我们希望保留订单和库存变更,但记录“通知失败”

-- ✅ 设置保存点2:库存已扣,通知可重试
SAVEPOINT sp_inventory_deducted;

-- 发送通知(模拟失败)
-- CALL send_notification(1001, 'order_created');

-- 若失败,回滚通知逻辑(但保留订单和库存)
ROLLBACK TO SAVEPOINT sp_inventory_deducted;

-- ✅ 最终提交:订单和库存变更永久生效,通知可异步重试
COMMIT;

✅ Java 中对应场景(使用 @Transactional(propagation = REQUIRES_NEW) 实现):

@Transactional
public void createOrderAndNotify(Long userId, Long productId) {
    Order order = orderService.createOrder(userId, productId);  // ✅ 事务1:创建订单

    try {
        inventoryService.deductStock(productId);  // ✅ 事务2:扣库存
    } catch (InsufficientStockException e) {
        // 记录日志,但不抛出,让外层事务继续
        log.warn("库存不足,订单已创建,等待补货");
    }

    try {
        notificationService.send(order);  // ✅ 事务3:发送通知
    } catch (NotificationException e) {
        // 记录失败,但不回滚订单和库存
        log.error("通知发送失败,待重试", e);
        // ✅ 不抛异常,事务继续
    }
}

✅ 团队规范建议:

  • SAVEPOINT 适用于多步骤、部分可失败、部分必须成功的复杂流程。
  • 不要滥用,复杂流程建议拆分为多个独立事务 + 消息队列(如 Kafka)。
  • 在 Java 中,可通过 @Transactional(propagation = REQUIRES_NEW) 模拟保存点行为。

四、TCL 与 Spring 事务注解的映射关系(Java 开发者必看)

PostgreSQL TCLSpring 注解说明
BEGIN@Transactional 自动开启无需手动写,Spring 在方法入口开启事务
COMMIT方法正常结束无异常 → 自动提交
ROLLBACK方法抛出未检查异常(RuntimeException)默认只对 RuntimeException 和 Error 回滚
ROLLBACK TO SAVEPOINT无直接对应通过 @Transactional(propagation = REQUIRES_NEW) 模拟
SAVEPOINT无直接对应通过嵌套事务或业务逻辑分层实现

✅ Java 中的事务控制最佳实践

@Service
public class OrderService {

    // ✅ 1. 默认:抛出 RuntimeException 时自动回滚
    @Transactional
    public void createOrder(Long userId, List<Long> productIds) {
        Order order = orderRepository.save(new Order(userId));
        for (Long id : productIds) {
            productService.decreaseStock(id);  // ✅ 如果抛出异常,整个事务回滚
        }
        paymentService.charge(userId, order.getTotal());  // ✅ 同样参与事务
    }

    // ✅ 2. 明确指定回滚异常(推荐)
    @Transactional(rollbackFor = {Exception.class})
    public void processPayment(Long userId, BigDecimal amount) {
        // 任何 Exception 都回滚(包括自定义业务异常)
    }

    // ✅ 3. 指定只在特定异常时回滚
    @Transactional(rollbackFor = PaymentFailedException.class)
    public void payWithCard(Long userId, String cardNumber) {
        // 仅当支付失败时回滚,其他异常不回滚(慎用)
    }

    // ✅ 4. 指定不回滚(非事务性操作)
    @Transactional(noRollbackFor = {NotificationException.class})
    public void createOrderAndNotify(Long userId, Long productId) {
        createOrder(userId, productId);
        notifyUser(userId);  // ✅ 即使通知失败,订单仍保存
    }

    // ✅ 5. 嵌套事务:模拟 SAVEPOINT(推荐用于“部分失败”场景)
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void deductStock(Long productId) {
        // 独立事务,即使外层回滚,此事务仍提交
        productRepository.decreaseStock(productId);
    }

    // ✅ 6. 事务传播行为:必须了解
    // REQUIRED(默认):已有事务则加入,无则新建
    // REQUIRES_NEW:无论是否有事务,都新建一个独立事务
    // NOT_SUPPORTED:挂起当前事务,以非事务方式执行
    // NEVER:禁止在事务中执行,否则报错
}

✅ 团队规范建议:

  • 默认使用 @Transactional,不加参数,但必须理解其默认行为。
  • 所有涉及多表更新、跨服务操作的方法,必须加 @Transactional。
  • 禁止在事务中调用外部 HTTP API、MQ、邮件服务,会导致事务挂起、连接池耗尽。
  • 异步操作(如发通知)应使用 @Async + 消息队列,不要在事务内阻塞等待。

五、TCL 企业级最佳实践与避坑指南(Java 开发者必看)

项目推荐做法禁止行为
✅ 事务边界方法粒度控制,一个业务动作一个事务在循环中调用 @Transactional 方法
✅ 异常处理事务内抛出 RuntimeException 触发回滚catch 异常后不抛出,导致事务静默提交
✅ 事务时长事务必须短小精悍(< 500ms)在事务中执行网络请求、文件上传、复杂计算
✅ 连接池配置 HikariCP 连接超时(connectionTimeout=30000)无超时,事务卡死导致连接池耗尽
✅ 死锁预防所有事务按固定顺序访问资源(如先锁用户,再锁订单)事务中并发访问资源顺序不一致
✅ 隔离级别默认 READ COMMITTED 即可,避免 SERIALIZABLE 性能开销无脑设置 SERIALIZABLE
✅ 测试事务使用 TestContainers + @Transactional 测试数据库操作用 H2 内存数据库测试事务逻辑(不一致)
✅ 监控事务开启 log_min_duration_statement = 500,监控慢事务不监控,生产环境事务卡死才发现
✅ 审计事务记录事务开始时间、结束时间、操作人、业务ID无日志,出问题无法追溯
✅ 异步解耦事务内只做数据库操作,异步任务用消息队列在事务中调用 @Async 方法(可能导致事务失效)

六、实战场景:订单系统事务最佳实践(完整链路)

场景:用户下单 → 扣库存 → 创建订单 → 扣积分 → 发送通知

@Service
@Transactional  // ✅ 整个下单流程在一个事务中
public class OrderService {

    @Autowired
    private ProductRepository productRepo;

    @Autowired
    private OrderRepository orderRepo;

    @Autowired
    private UserService userService;

    @Autowired
    private NotificationService notificationService;

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    public void placeOrder(Long userId, Long productId, Integer quantity) {
        
        // ✅ 1. 查询并锁定库存(行级锁,防超卖)
        Product product = productRepo.findForUpdate(productId); // ✅ SELECT ... FOR UPDATE
        if (product.getStock() < quantity) {
            throw new InsufficientStockException("库存不足");
        }

        // ✅ 2. 扣库存(DML)
        productRepo.decreaseStock(productId, quantity);

        // ✅ 3. 创建订单(DML)
        Order order = new Order(userId, productId, quantity, product.getPrice());
        order = orderRepo.save(order);

        // ✅ 4. 扣积分(DML)
        userService.deductPoints(userId, 10);

        // ✅ 5. 发送通知(**异步!不在事务内阻塞**)
        // ✅ 使用消息队列,事务提交后异步发送,保证最终一致性
        kafkaTemplate.send("order-created-topic", 
            "{\"orderId\":" + order.getId() + ",\"userId\":" + userId + "}");

        // ✅ 6. 此时事务结束,自动 COMMIT
        // 所有数据库操作原子性完成
        // 通知失败?没关系,消费者会重试,不影响订单创建
    }
}

✅ 为什么这样设计?

  • 事务内只做数据库操作 → 快、安全、可回滚。
  • 外部调用(通知)异步化 → 避免事务挂起、连接池耗尽。
  • 消息队列保证最终一致性 → 通知失败可重试,订单不会丢失。
  • 使用 FOR UPDATE 锁定库存行 → 防止并发超卖。

七、TCL 高级技巧:如何避免死锁?

死锁是多事务并发访问资源顺序不一致导致的“互相等待”。

✅ 死锁示例(错误写法):

// 事务 A
@Transactional
public void transferA() {
    accountService.debit(1);   // 先锁用户1
    accountService.credit(2);  // 再锁用户2
}

// 事务 B(并发)
@Transactional
public void transferB() {
    accountService.debit(2);   // 先锁用户2
    accountService.credit(1);  // 再锁用户1
}

⚠️ 结果:A 等 B 释放用户2,B 等 A 释放用户1 → 死锁!

✅ 正确写法:统一资源访问顺序

// 所有事务都按“用户ID升序”访问
@Transactional
public void transferA() {
    if (fromUserId < toUserId) {
        debit(fromUserId);
        credit(toUserId);
    } else {
        debit(toUserId);   // ✅ 先操作ID小的
        credit(fromUserId);
    }
}

✅ 团队规范建议:

  • 所有涉及多资源的操作,必须按固定顺序访问(如按 ID 排序)。
  • 使用 SELECT ... FOR UPDATE 时,必须在 WHERE 中使用索引字段,否则锁表。
  • 开启 log_lock_waits = on 和 deadlock_timeout = 1s,监控锁等待。

八、TCL 审查清单(团队 Code Review 必查项)

检查项是否通过说明
✅ 所有涉及多表更新的方法是否加 @Transactional?☐必须!否则数据不一致
✅ 事务内是否调用了外部 HTTP/MQ/邮件服务?☐禁止!应异步解耦
✅ 事务内是否执行了长时间计算或文件读写?☐禁止!事务必须短
✅ 是否在事务中 catch 异常后不抛出?☐必须抛出,否则不回滚
✅ 是否使用 @Transactional(propagation = REQUIRES_NEW) 模拟局部提交?☐仅用于“部分失败不影响主流程”场景
✅ 是否在事务中使用 @Async?☐不推荐,事务可能失效
✅ 是否使用 SELECT ... FOR UPDATE 防止超卖?☐库存、优惠券、秒杀必须用
✅ 是否监控慢事务(>500ms)?☐必须配置 log_min_duration_statement
✅ 是否测试事务回滚?☐使用 @Rollback 注解测试回滚逻辑
✅ 是否使用 TestContainers 而非 H2 测试事务?☐H2 事务行为与 PG 不一致,测试无效

九、总结:TCL 的三条铁律

铁律说明
🔒 1. 所有涉及多个数据库操作的业务,必须用 @Transactional 包裹没有事务,就没有一致性
⏱️ 2. 事务必须短、快、轻,禁止在事务内做任何 I/O 操作事务越长,死锁、锁表、连接池耗尽风险越高
🔄 3. 外部依赖(通知、支付、物流)必须异步化,使用消息队列实现最终一致性不要让事务等外部系统,要让外部系统等事务

✅ 终极建议:
数据库事务不是“技术细节”,而是业务连续性的保障。
一个错误的事务设计,可能导致用户支付成功但订单未创建,
一个正确的事务设计,能让系统在崩溃后依然保持数据完整。


📌 下一步行动建议:

  1. 将本文档作为团队《事务管理规范》核心章节,加入代码审查清单。
  2. 在 GitLab CI 中集成 pg_stat_statements,自动识别慢事务(>500ms)。
  3. 组织一次“事务与死锁实战演练”:模拟两个并发下单,观察死锁日志。
  4. 制定《事务最佳实践手册》:包含“能用事务的场景”与“不能用事务的场景”对照表。
  5. 为所有核心服务(订单、支付、库存)编写事务测试用例,确保回滚逻辑正确。

DML实战精要:SELECT/INSERT/UPDATE/DELETE的防错工程指南 DML(数据操纵语言)是数据库操作的核心能力,涵盖SELECT、INSERT、UPDATE、DELETE四大命令,其本质并非语法记忆,而是基于事务控制(TCL)、索引优化与约束机制的数据精准干预。理解DML需从MVCC并发模型、执行计划(EXPLAIN ANALYZE)和隐式类型转换等底层原理出发,技术价值在于保障数据一致性、提升ETL效率、规避线上事故。典型应用场景包括实时订单对账、风控规则计算、用户等级批量升级及历史数据归档治理。本文聚焦生产级DML工程实践,深度解析ON CONFLICT冲突处理、RE 阅读详情

相关推荐

数据库国产化探究及升级改造过程指导

当前官网最新版本为DM8,相较于目前主流产品架构:不同特性依靠不同内核去实现,DM8独特采用了双存储引擎架构,行存储引擎和列存储引擎可相互配合、协同工作。同时实现了计算层和存储层的分离,同一内核既支持共享存储式集群,也支持分布式事务集群。

企业实战系列集 ●●● https://ximenjianxue.blog.youkuaiyun.com 5368

PostgreSQL DML(数据操作语言)深度详解文档

本文为Java后端开发者(尤其是Spring Boot团队)提供了一份PostgreSQL DML(数据操作语言)深度详解文档,涵盖定义、核心语句、企业级最佳实践和真实场景示例。文档强调DML作为业务系统最频繁的数据库操作,直接影响系统稳定性,并详细解析INSERT、UPDATE、DELETE、MERGE四大核心语句,提供生产环境推荐写法。重点包括:批量插入替代单条循环、ON CONFLICT实现Upsert、JSONB字段操作、UPDATE必须带WHERE条件等规范,旨在帮助团队实现安全、高效、可追溯的数

python15397的博客 989

【无标题】EXCEL实现刷题

运用Excel开发的刷题工具,具有普遍实用性,可将WORD的试题自动导入并实现刷题。

weixin_44081794的博客 2970

PostgreSQL基础知识-DML深度解析

PostgreSQL是一款功能强大的开源关系型数据库,支持SQL标准及现代数据库特性。其SQL命令分为五大类:DDL(定义数据库结构)、DML(数据增删改查)、DQL(数据查询)、DCL(权限控制)和TCL(事务管理)。这种分类有助于理解不同命令的作用范围,如TRUNCATE虽功能类似DELETE但属于DDL。PostgreSQL以可靠性著称,支持事务回滚等高级特性,适用于各类操作系统环境。

ejinxian的专栏 306

网格自适应实战 | 攻克超弹性体大变形不收敛难题

本文针对超弹性体(如橡胶)在大变形仿真中因网格严重扭曲导致计算不收敛的难题,提供了基于ANSYS网格自适应技术的实战解决方案。文章详细阐述了从问题诊断、模型准备到核心参数设置的完整流程,并介绍了结合混合U-P单元技术的进阶组合策略,有效攻克了材料压缩等场景下的仿真收敛问题。

week9的博客 515

机器学习的学习准则(期望风险最小化、经验风险最小化、结构风险最小化)

要评价模型f(x, θ)的好坏,可通过期望风险R(θ)来衡量:求期望损失R(θ)不仅需要知道损失函数还需要知道真实分布,损失函数可以通过一定的准则计算得到,但是样本空间的真实分布是未知的。所以不能直接求R(θ)。期望风险R(θ)无法计算,给定一个训练集D =,我们可以计算经验风险,经验风险就是在训练集上的平均损失:为了解决过拟合问题,引入了参数正则化来限制模型的能力。使其不要过度的最小化经验风险。这种准则就是结构风险最小化准则

... 2222

南大通用GBase 8c企业级数据库特性之兼容性

南大通用 GBase 8c 是一款高性能的分布式数据库管理系统,支持多种存储模式(行存、列存、内存等)和多种部署形态(单机、主备、分布式)。它具有高性能、高可用性、弹性伸缩和高安全性等特点。GBase 8c 适用于物理机、虚拟机、容器、私有云和公有云等多种环境,广泛应用于金融、电信、政务等领域。高性能:基于shared nothing架构,支持高并发事务处理。高可用性:支持多地部署和容灾能力。低成本:通过资源调度精细化和集群运维智能化实现成本优化。

weixin_47390342的博客 1035

解决Android UVCCamera stopPreview 报错 崩溃 闪退 问题

在使用libuvccamera库的UVCCamera时,经常在调用stopPreview关闭预览的时候,app直接崩溃闪退了,经过综合各种修改源码的方案,已解决这个问题,以下请参考: 首先找到android_usbfs.c,linux_usbfs.c两个原文件,在两个文件中都可以找到这段代码,按如下示例修改: 修改前: for (i = 0; i < num_urbs; i++) { if (urb == tpriv->iso_urbs[i]) { urb_idx = i + 1;

hanye2020的博客 3576

SQL从入门到实战:掌握数据库操作、性能优化与安全防御

SQL(结构化查询语言)是关系型数据库管理的核心,它通过DDL、DML、DCL和TCL等语句实现对数据的定义、操纵和控制。其工作原理是将用户指令转换为数据库引擎可执行的操作,高效完成数据存取。掌握SQL不仅能够提升数据处理效率,更是构建稳定数据应用的基础,广泛应用于数据分析、Web开发和系统运维等领域。在实际应用中,SQL注入等安全风险和慢查询等性能问题尤为关键。通过参数化查询和索引优化等技术,可以有效防范安全漏洞并提升执行效率。本文聚焦SQL注入防御和慢SQL优化,结合具体场景,系统讲解从基础语法到高级实

weixin_30621711的博客 368

华为OD机考2025C卷 - 高矮个子排队(Java & Python& JS & C++ & C)

华为OD机考2025C卷 - 高矮个子排队。提供在线OJ刷题。Java、C++、Python、C语言、JavaScript题解,并提供完整思路讲解。

算法大师! 1680

基于龙虾Claw的会议纪要自动提取与重点内容总结办公场景实践

本文介绍如何使用龙虾Claw构建会议纪要自动提取与重点内容总结系统,实现会议内容的智能处理。

一键难忘的博客 251

数据库核心技术解析:从数据模型、事务ACID到索引与并发控制

数据库作为现代信息系统的核心,其价值在于高效、安全、可靠地管理数据。理解其基本概念与原理是掌握数据库技术的基石。数据模型定义了数据的组织方式,从经典的关系模型到新兴的文档、键值、图及向量模型,各有其适用场景。事务通过ACID属性(原子性、一致性、隔离性、持久性)确保数据操作的可靠性,是数据安全的守护神。在技术实现层面,存储引擎如InnoDB采用页式存储与缓冲池优化I/O;索引(尤其是B+树索引)通过减少磁盘访问次数极大提升查询效率;并发控制机制(如锁与MVCC)管理多用户并行访问时的数据一致性与性能。这些原

389

【YOLO11改进 - C3k2融合】C3k2融合DWRSeg二次创新C3k2_DWR:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目标检测

【YOLO11改进 - C3k2融合】C3k2DWRSeg二次创新C3k2_DWR:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目标检测

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 1054

从 “什么是 MySQL“ 到库与表的完整操作(MySQL基础篇)

MySQL 本质上是一个网络服务:mysql 是客户端,mysqld 是服务端(守护进程)。换句话说,这是一个基于C/S(Client/Server)模式的软件。mysql:客户端程序(CLI 命令行工具),用户敲命令的地方;mysqld:服务端守护进程,真正干活的地方 —— 接收指令、分析语法、执行操作、返回结果。客户端和服务端可以不在同一台机器(通过 -h 指定 IP 连接),也可以在同一台机器 —— 单机开发时,你的主机上同时运行着两个进程。

bksczm的博客 685

蓝牙攻防实战指南:低功耗蓝牙

Bluetooth Low Energy(也称Bluetooth Smart)是经典蓝牙(Bluetooth Classic)的演进版本,设计目标是实现极低功耗,适用于无需频繁更换电池的设备,如智能手环、健康监测器、蓝牙标签等。Bluetooth Low Energy 是一项极具前景的无线通信技术,它以极低的功耗实现了短距离高效通信,广泛应用于智能设备和物联网领域。然而,其简化的协议结构和配对机制也带来了不小的安全挑战。

idlecloud0105的博客 682

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

mysql数据库的了解和使用

mysql数据库的了解和使用

xgq_111的博客 2030

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

MySQL实战入门:从零到精通的核心技能与性能优化指南

如果你正在寻找一套能让你从零开始,快速掌握 MySQL 数据库核心技能,并能立即应用到实际工作中的学习路径,那么这篇文章就是为你准备的。这不是一个传统的、按部就班的教科书式教程,而是一套聚焦于“能用、会用、用好”的实战指南。我们将直接切入核心,从环境搭建、基础语法到性能优化,全程以解决实际问题为导向,目标是让你在最短时间内,具备独立完成数据库设计、开发和优化的能力。 本文的核心在于“实战”二字。我们将跳过冗长的理论铺垫,直接上手操作。你会学到如何在主流操作系统上快速部署 MySQL,如何编写高效的 SQL

all00747的博客 382

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

30天掌握MySQL:从SQL语法到性能优化的实战指南

如果你正在寻找一套能让你从零开始,系统掌握 MySQL 数据库,并能快速应用到实际工作中的学习路径,那么这篇文章就是为你准备的。我们直接切入核心:这不是一个泛泛而谈的概念教程,而是一套聚焦于“30天搞定SQL语法与实战优化”的实战指南。它旨在解决初学者面对海量资料无从下手、学习过程枯燥、理论与实践脱节的核心痛点。 这套教程的核心价值在于其结构化、实战化的内容设计。它从最基础的安装配置讲起,覆盖了SQL语法的方方面面,并最终深入到数据库性能优化的高级领域。对于开发者、数据分析师、运维人员或任何需要与数据库打交

weixin_30336061的博客 324

fast-lio2复现跑avia数据集

本文详细介绍了在Windows WSL2中安装Ubuntu 22.04并配置ROS2 Humble环境的全过程,涵盖系统初始化、ROS2安装、Livox雷达驱动编译及FAST-LIO2 ROS2版本的构建与验证。通过完整数据集回放与建图测试,成功实现点云地图生成与轨迹记录,并利用evo工具完成轨迹分析与可视化。最终输出包括累积点云地图、位姿轨迹及实验配置文件,为后续精度评估与复现提供基准。

chase_my_dream的博客 319

Ubuntu 修复 FinalShell 任务栏齿轮图标

FinalShell 可以正常启动,但任务栏显示默认齿轮图标。本次环境为 Ubuntu、X11,图标文件存在且有效。最终通过在用户级.desktop文件中加入,重新启动并固定应用,成功解决。st是本次实际测得的窗口标识。其他版本或安装方式应先测量,不要直接套用。

To be a better man 194

【T113】SDK Tina5.0 V1.2 使用记录(一)基本使用,初次编译等

SDK名称发行方其他描述全志官方tina2.0,仅支持 openwrt全志官方tina5.0 v1.2,支持 openwrt, buildroot百问网非官方,支持buildroot,用于开发板100ask_t113-pro。

似水流年 103

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

要努力去发光,而不是被照亮~ 112

在Codex 让AI模型 拥有长期智能记忆

本文介绍Claude-Mem V15新功能——智能记忆召回,解决AI遗忘、重复提示、执行不一致等问题。通过本地部署claude-mem,实现自动记录决策(如数据库选型)、跨会话智能召回,支持记忆写入、检索、遗忘全流程闭环。相比传统记忆方案,其基于Hooks自动捕获工具调用,结构化存储,可追溯、可共享、可清理,显著提升工程效率与协作一致性,是长期项目中理想的“工作黑匣子”与“工程脑”。

米莱虾 253

Spring Boot 数据源与 MyBatis(-Plus) 自定义配置详解

本文详解 Spring Boot 中单数据源环境下 HikariCP 与 MyBatis-Plus 的自定义配置。通过手动声明 SqlSessionFactory,实现下划线转驼峰、日志输出、一级缓存策略等精细化控制。结合 HikariCP 核心参数调优(如最大连接数、连接生命周期),确保高性能与稳定性。适用于仅需访问单一数据库的场景,避免多数据源复杂性,兼顾性能与可维护性。

BADAO_LIUMANG_QIZHI的博客 190

45-存储过程与函数

匿名块跑完就没了,想下次再用只能复制粘贴。给块起个名字存进数据库,就成了存储过程与函数:一次编译、处处调用、权限收口,还能让 Java 侧少拼 SQL。这篇讲封装、调用、限制与排错的完整套路。CREATE OR REPLACE 覆盖式创建,事务由调用方控制;参数三模式 IN 只进、OUT 只出、IN OUT 双向,OUT 参数调用时要备好变量接;调用三姿势 EXEC、CALL、匿名块,命名传参=>最清晰;函数必有 RETURN,想在 SQL 里调用就不能碰 DML 和事务控制;

yuhou25的博客 151

数据库乐观锁深度解析:MySQL、PostgreSQL 实战 + Spring Boot 集成指南

Oracle 提供了ORA_ROWSCN伪列(System Change Number),记录最后修改行的 SCN,类似 PostgreSQL 的xmin。实践中通常仍使用 version 字段方案,逻辑与 MySQL 完全相同。-- Oracle:通过 ORA_ROWSCN 实现乐观锁-- 更新时比对 SCN// 自定义注解// AOP 切面@Aspect@Component@Slf4jtry {

yjc_1111的专栏 392
上一篇: PostgreSQL DCL(数据控制语言)深度详解文档
下一篇: PostgreSQL 其他常用 SQL 操作深度详解文档
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值