@Test public void testCreateTableToBeTransactional() throws Exception { Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); Connection conn = DriverManager.getConnection(getUrl(), props); String ddl = "CREATE TABLE TEST_TRANSACTIONAL_TABLE (k varchar primary key) transactional=true"; conn.createStatement().execute(ddl); PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class); PTable table = pconn.getTable(new PTableKey(null, "TEST_TRANSACTIONAL_TABLE")); HTableInterface htable = pconn.getQueryServices().getTable(Bytes.toBytes("TEST_TRANSACTIONAL_TABLE")); assertTrue(table.isTransactional()); assertTrue( htable .getTableDescriptor() .getCoprocessors() .contains(TransactionProcessor.class.getName())); try { ddl = "ALTER TABLE TEST_TRANSACTIONAL_TABLE SET transactional=false"; conn.createStatement().execute(ddl); fail(); } catch (SQLException e) { assertEquals(SQLExceptionCode.TX_MAY_NOT_SWITCH_TO_NON_TX.getErrorCode(), e.getErrorCode()); } HBaseAdmin admin = pconn.getQueryServices().getAdmin(); HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("TXN_TEST_EXISTING")); desc.addFamily(new HColumnDescriptor(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES)); admin.createTable(desc); ddl = "CREATE TABLE TXN_TEST_EXISTING (k varchar primary key) transactional=true"; conn.createStatement().execute(ddl); assertEquals( Boolean.TRUE.toString(), admin .getTableDescriptor(TableName.valueOf("TXN_TEST_EXISTING")) .getValue(TxConstants.READ_NON_TX_DATA)); // Should be ok, as HBase metadata should match existing metadata. ddl = "CREATE TABLE IF NOT EXISTS TEST_TRANSACTIONAL_TABLE (k varchar primary key)"; try { conn.createStatement().execute(ddl); fail(); } catch (SQLException e) { assertEquals(SQLExceptionCode.TX_MAY_NOT_SWITCH_TO_NON_TX.getErrorCode(), e.getErrorCode()); } ddl += " transactional=true"; conn.createStatement().execute(ddl); table = pconn.getTable(new PTableKey(null, "TEST_TRANSACTIONAL_TABLE")); htable = pconn.getQueryServices().getTable(Bytes.toBytes("TEST_TRANSACTIONAL_TABLE")); assertTrue(table.isTransactional()); assertTrue( htable .getTableDescriptor() .getCoprocessors() .contains(TransactionProcessor.class.getName())); }
/* * 为表添加数据(适合知道有多少列族的固定表) * * @rowKey rowKey * * @tableName 表名 * * @column1 第一个列族列表 * * @value1 第一个列的值的列表 * * @column2 第二个列族列表 * * @value2 第二个列的值的列表 */ public static void addData( String rowKey, String tableName, String[] column1, String[] value1, String[] column2, String[] value2) throws IOException { Put put = new Put(Bytes.toBytes(rowKey)); // 设置rowkey HTableInterface htable = conn.getTable(tableName); HColumnDescriptor[] columnFamilies = htable .getTableDescriptor() // 获取所有的列族 .getColumnFamilies(); for (int i = 0; i < columnFamilies.length; i++) { String familyName = columnFamilies[i].getNameAsString(); // 获取列族名 if (familyName.equals("article")) { // article列族put数据 for (int j = 0; j < column1.length; j++) { put.add(Bytes.toBytes(familyName), Bytes.toBytes(column1[j]), Bytes.toBytes(value1[j])); } } if (familyName.equals("author")) { // author列族put数据 for (int j = 0; j < column2.length; j++) { put.add(Bytes.toBytes(familyName), Bytes.toBytes(column2[j]), Bytes.toBytes(value2[j])); } } } htable.put(put); // System.out.println("add data Success!"); }
public static void createTable(String tableName) { long start = System.currentTimeMillis(); try { HTableInterface htable = conn.getTable(tableName); List<Put> putList = new ArrayList<Put>(); HColumnDescriptor[] columnFamilies = htable.getTableDescriptor().getColumnFamilies(); String[] family = {"article", "author"}; creatTable(tableName, family); String[] column1 = {"title", "content", "tag"}; String[] column2 = {"name", "nickname"}; for (int i = 1; i <= 1000000; i++) { DecimalFormat format = new DecimalFormat("00000000"); String rowKey = format.format(i); // System.out.println("==| insert"+rowKey); String[] valueOfArticle = {"title" + i, "content" + i, "tag" + i}; String[] valueOfAuthor = {"name" + i, "nickname" + i}; // addData(rowKey, tableName, column1, valueOfArticle, column2, // valueOfAuthor); Put put = new Put(Bytes.toBytes(rowKey)); // 设置rowkey for (int colIndex = 0; colIndex < columnFamilies.length; colIndex++) { String familyName = columnFamilies[colIndex].getNameAsString(); // 获取列族名 if (familyName.equals("article")) { // article列族put数据 for (int k = 0; k < column1.length; k++) { put.add( Bytes.toBytes(familyName), Bytes.toBytes(column1[k]), Bytes.toBytes(valueOfArticle[k])); } } if (familyName.equals("author")) { // author列族put数据 for (int k = 0; k < column2.length; k++) { put.add( Bytes.toBytes(familyName), Bytes.toBytes(column2[k]), Bytes.toBytes(valueOfAuthor[k])); } } } putList.add(put); if (i % 10000 == 0) { htable.put(putList); putList = new ArrayList<Put>(); } } long end = System.currentTimeMillis(); long used = end - start; System.out.println("data insert finished used " + used + " ms"); } catch (Exception e) { e.printStackTrace(); } }
@Ignore @Test public void testNonTxToTxTableFailure() throws Exception { Connection conn = DriverManager.getConnection(getUrl()); // Put table in SYSTEM schema to prevent attempts to update the cache after we disable // SYSTEM.CATALOG conn.createStatement() .execute("CREATE TABLE SYSTEM.NON_TX_TABLE(k INTEGER PRIMARY KEY, v VARCHAR)"); conn.createStatement().execute("UPSERT INTO SYSTEM.NON_TX_TABLE VALUES (1)"); conn.commit(); // Reset empty column value to an empty value like it is pre-transactions HTableInterface htable = conn.unwrap(PhoenixConnection.class) .getQueryServices() .getTable(Bytes.toBytes("SYSTEM.NON_TX_TABLE")); Put put = new Put(PInteger.INSTANCE.toBytes(1)); put.add( QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, ByteUtil.EMPTY_BYTE_ARRAY); htable.put(put); HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin(); admin.disableTable(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME); try { // This will succeed initially in updating the HBase metadata, but then will fail when // the SYSTEM.CATALOG table is attempted to be updated, exercising the code to restore // the coprocessors back to the non transactional ones. conn.createStatement().execute("ALTER TABLE SYSTEM.NON_TX_TABLE SET TRANSACTIONAL=true"); fail(); } catch (SQLException e) { assertTrue( e.getMessage().contains(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME + " is disabled")); } finally { admin.enableTable(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME); admin.close(); } ResultSet rs = conn.createStatement().executeQuery("SELECT k FROM SYSTEM.NON_TX_TABLE WHERE v IS NULL"); assertTrue(rs.next()); assertEquals(1, rs.getInt(1)); assertFalse(rs.next()); htable = conn.unwrap(PhoenixConnection.class) .getQueryServices() .getTable(Bytes.toBytes("SYSTEM.NON_TX_TABLE")); assertFalse( htable .getTableDescriptor() .getCoprocessors() .contains(TransactionProcessor.class.getName())); assertEquals( 1, conn.unwrap(PhoenixConnection.class) .getQueryServices() .getTableDescriptor(Bytes.toBytes("SYSTEM.NON_TX_TABLE")) .getFamily(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES) .getMaxVersions()); }
@Test public void testNonTxToTxTable() throws Exception { Connection conn = DriverManager.getConnection(getUrl()); conn.createStatement().execute("CREATE TABLE NON_TX_TABLE(k INTEGER PRIMARY KEY, v VARCHAR)"); conn.createStatement().execute("UPSERT INTO NON_TX_TABLE VALUES (1)"); conn.createStatement().execute("UPSERT INTO NON_TX_TABLE VALUES (2, 'a')"); conn.createStatement().execute("UPSERT INTO NON_TX_TABLE VALUES (3, 'b')"); conn.commit(); conn.createStatement().execute("CREATE INDEX IDX ON NON_TX_TABLE(v)"); // Reset empty column value to an empty value like it is pre-transactions HTableInterface htable = conn.unwrap(PhoenixConnection.class) .getQueryServices() .getTable(Bytes.toBytes("NON_TX_TABLE")); List<Put> puts = Lists.newArrayList( new Put(PInteger.INSTANCE.toBytes(1)), new Put(PInteger.INSTANCE.toBytes(2)), new Put(PInteger.INSTANCE.toBytes(3))); for (Put put : puts) { put.add( QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, ByteUtil.EMPTY_BYTE_ARRAY); } htable.put(puts); conn.createStatement().execute("ALTER TABLE NON_TX_TABLE SET TRANSACTIONAL=true"); htable = conn.unwrap(PhoenixConnection.class) .getQueryServices() .getTable(Bytes.toBytes("NON_TX_TABLE")); assertTrue( htable .getTableDescriptor() .getCoprocessors() .contains(TransactionProcessor.class.getName())); htable = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes("IDX")); assertTrue( htable .getTableDescriptor() .getCoprocessors() .contains(TransactionProcessor.class.getName())); conn.createStatement().execute("UPSERT INTO NON_TX_TABLE VALUES (4, 'c')"); ResultSet rs = conn.createStatement() .executeQuery("SELECT /*+ NO_INDEX */ k FROM NON_TX_TABLE WHERE v IS NULL"); assertTrue( conn.unwrap(PhoenixConnection.class) .getTable(new PTableKey(null, "NON_TX_TABLE")) .isTransactional()); assertTrue(rs.next()); assertEquals(1, rs.getInt(1)); assertFalse(rs.next()); conn.commit(); conn.createStatement().execute("UPSERT INTO NON_TX_TABLE VALUES (5, 'd')"); rs = conn.createStatement().executeQuery("SELECT k FROM NON_TX_TABLE"); assertTrue( conn.unwrap(PhoenixConnection.class) .getTable(new PTableKey(null, "IDX")) .isTransactional()); assertTrue(rs.next()); assertEquals(1, rs.getInt(1)); assertTrue(rs.next()); assertEquals(2, rs.getInt(1)); assertTrue(rs.next()); assertEquals(3, rs.getInt(1)); assertTrue(rs.next()); assertEquals(4, rs.getInt(1)); assertTrue(rs.next()); assertEquals(5, rs.getInt(1)); assertFalse(rs.next()); conn.rollback(); rs = conn.createStatement().executeQuery("SELECT k FROM NON_TX_TABLE"); assertTrue(rs.next()); assertEquals(1, rs.getInt(1)); assertTrue(rs.next()); assertEquals(2, rs.getInt(1)); assertTrue(rs.next()); assertEquals(3, rs.getInt(1)); assertTrue(rs.next()); assertEquals(4, rs.getInt(1)); assertFalse(rs.next()); }