CREATE PROCEDURE FROM CLASS — Defines a stored procedure associated with a Java class.
CREATE PROCEDURE
[PARTITION ON TABLE table-name COLUMN column-name [PARAMETER
position]]
[ALLOW role-name [,...]]
FROM CLASS class-name
CREATE DIRECTED PROCEDURE
[ALLOW role-name [,...]]
FROM CLASS class-name
CREATE COMPOUND PROCEDURE
[ALLOW role-name [,...]]
FROM CLASS class-name
You must declare stored procedures to make them accessible to client applications and the sqlcmd utility. CREATE PROCEDURE FROM CLASS lets you declare stored procedures that are written as Java classes. The class-name is the name of the Java class.
Before you declare the stored procedure, you must create, compile, and load the associated Java class. It is usually easiest to do this by compiling all of your Java stored procedures and packaging the resulting class files into a single JAR file that can be loaded once. For example:
$ javac -d ./obj src/procedures/*.java $ jar cvf myprocs.jar –C obj . $ sqlcmd 1> LOAD CLASSES myprocs.jar; 2> CREATE PROCEDURE FROM CLASS procedures.AddCustomer;
You can create four types of stored procedures:
Multi-Partition Procedures — By default, the CREATE PROCEDURE statement declares a multi-partition procedure. A multi-partition procedure runs as a single transaction and has access to data from the entire database. However, it also means that the procedure will access all of the partitions at once, blocking the transaction queues until the procedure is done.
Single-Partition Procedures — If you include the PARTITION ON clause, the procedure is partitioned and runs on only one partition of the database. The partition it runs on is determined by the value of one of the parameters you pass to the procedure at runtime, as described below.
Directed Procedures — If you include the DIRECTED clause, the procedure is a directed
procedure and will run separate transactions on each of the partitions. However, the individual transactions are not
coordinated. Directed procedures must be invoked as a scheduled task or using the
callAllPartitionProcedure
method. See Section 7.5, “Directed Procedures: Distributing Transactions to Every Partition” and the description of
the CREATE TASK statement for more information on directed procedures.
Compound Procedures — If you include the COMPOUND clause, and the specified class
extends the VoltCompoundProcedure
class, the procedure is defined as a compound procedure. Compound
procedures are not transactional, but can call multiple regular stored procedures, perform analysis
and error handling, and return custom results. See the chapter on Compound Procedures in the VoltDB Performance and
Customization Guide for more information.
When creating single-partitioned procedures, you specify the partitioning in the PARTITION ON clause. Partitioning a stored procedure means that the procedure executes within a unique partition of the database. The partition in which the procedure executes is chosen at runtime based on the table and column specified by table-name and column-name. By default, VoltDB uses the first parameter to the stored procedure as the partitioning value. However, you can use the PARAMETER clause to specify a different parameter. The position value specifies the parameter position, counting from zero. (In other words, position 0 is the first parameter, position 1 is the second, and so on.)
The specified table must be a partitioned table and cannot be an export stream or replicated table.
If security is enabled at runtime, only those roles named in the ALLOW clause (or with the ALLPROC or ADMIN permissions) have permission to invoke the procedure. If security is not enabled at runtime, the ALLOW clause is ignored and all users have access to the stored procedure.
A directed procedure is a special type of stored procedure, declared using the DIRECTED clause. Multi-partition procedures run as a single transaction with access to all partitions. Single-partitioned procedures run as a single transaction on one partition, determined by the table and column on which the procedure is partitioned. A directed procedure queues multiple transactions at once, one on each partition without regard to any specific table or partitioning column.
By running separate transactions on each partition, directed procedures do not block the partition queues the way multi-partition procedures do. However, there is no guarantee that the individual transactions are executed at the same time. Consequently, directed procedures are good for work activities that need access to all of the partitions but do not need to be coordinated as a single transaction. For example, cleanup tasks that delete orphaned records or update non-critical columns across the database.
Directed procedures are transactional and must obey the same rules as other stored procedures. That is, they are Java classes that extend voltProcedure, use the voltQueueSQL method to queue SQL statements, and they must be deterministic. (See Chapter 5, Designing Stored Procedures to Access the Database for more information about determinism and the structure of stored procedures.)
However, because of the different execution model of the directed procedure, you cannot call them with the
callProcedure
method the way you call partitioned or multi-partitioned procedures. Instead, directed
procedures are invoked using the callAllPartitionProcedure
method or as a scheduled task with the ON
PARTITIONS clause. See the description of the CREATE TASK statement for more information on invoking directed procedures as
an automated task.
A compound procedure is another special type of stored procedure, declared using the COMPOUND clause. Unlike all other procedures, compound procedures themselves are not transactional. That is, the procedure does not succeed or rollback as a unit. Instead, compound procedures let you call multiple regular stored procedures that are transactional, analyze their results, handle errors, and perform other program logic.
Because they can invoke multiple transactions, compound procedures are particularly useful for processing input from topics, where there is no client application to process the results of SQL queries. Compound procedures let you embed the processing of results and conditional programming into the procedure itself. The drawback is that, if anything unexpected happens, it is up to the procedure to handle any exceptions.
In general, compound procedures are intended for making multiple calls to single-partitioned procedures. However, compound procedures can call both partitioned and multi-partitioned procedures. And when it does call partitioned procedures, it can specify different partitioning values. So the compound procedure itself cannot be partitioned. It also runs in a separate queue from the transactional procedures it calls. See the chapter on Using Compound Procedures in the VoltDB Performance and Customization Guide for more information.
The following example declares a stored procedure matching the Java class MakeReservation. Note that the class name includes its location within the current class path (in this case, as a child of flight and procedures). However, the name itself, MakeReservation, must be unique within the schema because at runtime stored procedures are invoked by name only.
CREATE PROCEDURE FROM CLASS flight.procedures.MakeReservation;