在Android中使用sqlite事务时出现多个线程问题

时间:2012-10-25 06:17:38

标签: android sqlite android-sqlite

我在Android中使用sqlite事务:

SQLiteDatabase database = sqlite_helper.getWritableDatabase();

database.beginTransaction();
...
database.setTransactionSuccessful();
database.endTransaction();

我的问题是:
1.我应该将endTransaction()放在finally代码块中,如下所示:

try {
    database.beginTransaction();
    ...
    database.setTransactionSuccessful();
}
finally {
    database.endTransaction();
}

如果在数据库操作期间出现异常,数据库是否会在不使用“finally”的情况下自动回滚?

  1. 当事务未结束时,其他线程可以读取或写入相同的数据库吗?我听说Android中的sqlite是安全的线程,但我不确定它。我想在交易过程中会遇到一些问题。如果另一个线程使用相同的连接写入相同的数据库,是否会引发错误? 我在我的应用程序中发现了这个错误,但我不知道它是否与线程安全问题有关:
  2. android.database.sqlite.SQLiteMisuseException: library routine called out of sequence:

    ,编译时

    有没有人帮我回答这些问题?非常感谢!

3 个答案:

答案 0 :(得分:5)

1.您应该始终将endTransaction置于finally块

2. SQLite中的事务是线程安全的,请参阅文档http://www.sqlite.org/atomiccommit.html

答案 1 :(得分:1)

您应始终将endTransaction()放入finally块(另请参阅the docs)。 否则,数据库将无法注意到发生了异常。

结束事务的唯一方法是关闭连接,在这种情况下,SQLite会自动回滚任何活动事务。

只要一个连接写入数据库(这意味着事务处于活动状态),就不能读取或写入其他连接。因此,您应该注意不要忘记结束交易。

你永远不应该从多个线程写;如果一个线程结束事务而另一个线程仍然在写,会发生什么?

您的SQLiteMisuseException可能与您有关;没有看到代码就不可能说。

答案 2 :(得分:0)

是的,您应该使用finally块。这是我使用的一种简单的线程安全方法:

interface Props extends InterfaceState {
  rectWidth: number
  spaceBetweenRects: number
}

export class Labels extends React.Component<Props> {
  render() {
    const { rectWidth, labelRectHeight, spaceBetweenRects } = this.props

    const names = ['Cher', 'Madonna', 'Band Names That Are Ridiculously Long', 'U2']
    const rectHeight = labelRectHeight
    const paddingLeftRight = 0.05 * rectWidth
    const plusWidth = rectHeight / 2

    return (
      <g>
        {names.map((name, i) => {
          const y = i * labelRectHeight + i * spaceBetweenRects
          const maxTextwidth = rectWidth - plusWidth - 3 * paddingLeftRight // this is the maximum length that text can have

          return (
            <g key={i}>
              <React.Fragment>
                <rect x={0} y={y} width={rectWidth} height={rectHeight} fill={'#E4E9EB'} />
              </React.Fragment>

              <text
                ref={this.textRef}
                x={rectWidth - paddingLeftRight}
                y={y + rectHeight / 2}
                textAnchor="end"
                alignmentBaseline="middle"
              >
                {name}
              </text>
            </g>
          )
        })}
      </g>
    )
  }
}

synchronized 关键字将方法及其包含对象锁定,从而使其线程安全...